2 * lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, 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.
22 #ifndef LEMON_GRAPH_WRITER_H
23 #define LEMON_GRAPH_WRITER_H
27 #include <lemon/error.h>
28 #include <lemon/lemon_writer.h>
32 /// \addtogroup io_group
35 /// \brief The graph writer class.
37 /// The \c GraphWriter class provides the graph output.
38 /// Before you read this documentation it might be useful to read the general
39 /// description of \ref graph-io-page "Graph Input-Output".
41 /// If you don't need very sophisticated
42 /// behaviour then you can use the versions of the public function
43 /// \ref writeGraph() to output a graph (or a max flow instance etc).
46 /// you should first give writing commands to the writer. You can declare
47 /// write commands as \c NodeMap or \c EdgeMap writing and labeled Node and
51 /// GraphWriter<ListGraph> writer(std::cout, graph);
54 /// The \c writeNodeMap() function declares a \c NodeMap writing
55 /// command in the \c GraphWriter. You should give as parameter
56 /// the name of the map and the map object. The NodeMap writing
57 /// command with name "id" should write a unique map because it
58 /// is regarded as ID map (such a map is essential if the graph has edges).
61 /// IdMap<ListGraph, Node> nodeIdMap;
62 /// writer.writeNodeMap("id", nodeIdMap);
64 /// writer.writeNodeMap("coords", coords);
65 /// writer.writeNodeMap("color", colorMap);
68 /// With the \c writeEdgeMap() member function you can give an edge map
69 /// writing command similar to the NodeMaps.
72 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
73 /// edgeDescMap(graph);
74 /// writer.writeEdgeMap("descriptor", edgeDescMap);
76 /// writer.writeEdgeMap("weight", weightMap);
77 /// writer.writeEdgeMap("label", labelMap);
80 /// With \c writeNode() and \c writeEdge() functions you can
81 /// point out Nodes and Edges in the graph. For example, you can
82 /// write out the source and target of a maximum flow instance.
85 /// writer.writeNode("source", sourceNode);
86 /// writer.writeNode("target", targetNode);
88 /// writer.writeEdge("observed", edge);
91 /// After you give all write commands you must call the \c run() member
92 /// function, which executes all the writing commands.
98 /// \see DefaultWriterTraits
99 /// \see QuotedStringWriter
101 /// \see DescriptorMap
102 /// \see \ref GraphReader
103 /// \see \ref graph-io-page
104 /// \author Balazs Dezso
105 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
109 typedef _Graph Graph;
110 typedef typename Graph::Node Node;
111 typedef typename Graph::Edge Edge;
113 typedef _WriterTraits WriterTraits;
115 /// \brief Construct a new GraphWriter.
117 /// This function constructs a new GraphWriter to write the given graph
118 /// to the given stream.
119 GraphWriter(std::ostream& _os, const Graph& _graph)
120 : writer(new LemonWriter(_os)), own_writer(true),
121 nodeset_writer(*writer, _graph, std::string()),
122 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
123 node_writer(*writer, nodeset_writer, std::string()),
124 edge_writer(*writer, edgeset_writer, std::string()),
125 attribute_writer(*writer, std::string()) {}
127 /// \brief Construct a new GraphWriter.
129 /// This function constructs a new GraphWriter to write the given graph
130 /// to the given file.
131 GraphWriter(const std::string& _filename, const Graph& _graph)
132 : writer(new LemonWriter(_filename)), own_writer(true),
133 nodeset_writer(*writer, _graph, std::string()),
134 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
135 node_writer(*writer, nodeset_writer, std::string()),
136 edge_writer(*writer, edgeset_writer, std::string()),
137 attribute_writer(*writer, std::string()) {}
139 /// \brief Construct a new GraphWriter.
141 /// This function constructs a new GraphWriter to write the given graph
142 /// to the given LemonReader.
143 GraphWriter(LemonWriter& _writer, const Graph& _graph)
144 : writer(_writer), own_writer(false),
145 nodeset_writer(*writer, _graph, std::string()),
146 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
147 node_writer(*writer, nodeset_writer, std::string()),
148 edge_writer(*writer, edgeset_writer, std::string()),
149 attribute_writer(*writer, std::string()) {}
151 /// \brief Destruct the graph writer.
153 /// This function destructs the graph writer.
159 /// \brief Issue a new node map writing command for the writer.
161 /// This function issues a new <i> node map writing command</i> to the writer.
162 template <typename Map>
163 GraphWriter& writeNodeMap(std::string name, const Map& map) {
164 nodeset_writer.writeNodeMap(name, map);
169 /// \brief Issue a new node map writing command for the writer.
171 /// This function issues a new <i> node map writing command</i> to the writer.
172 template <typename Writer, typename Map>
173 GraphWriter& writeNodeMap(std::string name, const Map& map,
174 const Writer& writer = Writer()) {
175 nodeset_writer.writeNodeMap(name, map, writer);
180 /// \brief Issue a new edge map writing command for the writer.
182 /// This function issues a new <i> edge map writing command</i> to the writer.
183 template <typename Map>
184 GraphWriter& writeEdgeMap(std::string name, const Map& map) {
185 edgeset_writer.writeEdgeMap(name, map);
190 /// \brief Issue a new edge map writing command for the writer.
192 /// This function issues a new <i> edge map writing command</i> to the writer.
193 template <typename Writer, typename Map>
194 GraphWriter& writeEdgeMap(std::string name, const Map& map,
195 const Writer& writer = Writer()) {
196 edgeset_writer.writeEdgeMap(name, map, writer);
200 /// \brief Issue a new labeled node writing command to the writer.
202 /// This function issues a new <i> labeled node writing command</i>
204 GraphWriter& writeNode(std::string name, const Node& node) {
205 node_writer.writeNode(name, node);
209 /// \brief Issue a new labeled edge writing command to the writer.
211 /// This function issues a new <i> labeled edge writing command</i>
213 GraphWriter& writeEdge(std::string name, const Edge& edge) {
214 edge_writer.writeEdge(name, edge);
217 /// \brief Issue a new attribute writing command.
219 /// This function issues a new <i> attribute writing command</i>
221 template <typename Value>
222 GraphWriter& writeAttribute(std::string name, const Value& value) {
223 attribute_writer.writeAttribute(name, value);
227 /// \brief Issue a new attribute writing command.
229 /// This function issues a new <i> attribute writing command</i>
231 template <typename Writer, typename Value>
232 GraphWriter& writeAttribute(std::string name, const Value& value,
233 const Writer& writer) {
234 attribute_writer.writeAttribute<Writer>(name, value, writer);
238 /// \brief Conversion operator to LemonWriter.
240 /// Conversion operator to LemonWriter. It makes possible
241 /// to access the encapsulated \e LemonWriter, this way
242 /// you can attach to this writer new instances of
243 /// \e LemonWriter::SectionWriter. For more details see
244 /// the \ref rwbackground "Background of Reading and Writing".
245 operator LemonWriter&() {
249 /// \brief Executes the writing commands.
251 /// Executes the writing commands.
256 /// \brief Write the id of the given node.
258 /// It writes the id of the given node. If there was written an "id"
259 /// named node map then it will write the map value belonging to the node.
260 void writeId(std::ostream& os, const Node& item) const {
261 nodeset_writer.writeId(os, item);
264 /// \brief Write the id of the given edge.
266 /// It writes the id of the given edge. If there was written an "id"
267 /// named edge map then it will write the map value belonging to the edge.
268 void writeId(std::ostream& os, const Edge& item) const {
269 edgeset_writer.writeId(os, item);
277 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
278 EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
280 NodeWriter<Graph> node_writer;
281 EdgeWriter<Graph> edge_writer;
283 AttributeWriter<WriterTraits> attribute_writer;
288 /// \brief Write a graph to the output.
290 /// It is a helper function to write a graph to the given output
291 /// stream. It gives back a GraphWriter object and this object
292 /// can write more maps, labeled nodes and edges and attributes.
293 /// \warning Do not forget to call the \c run() function.
295 /// \param os The output stream.
296 /// \param g The graph.
297 template <typename Graph>
298 GraphWriter<Graph> graphWriter(std::ostream& os, const Graph &g) {
299 return GraphWriter<Graph>(os, g);
302 /// \brief Write a graph to the output.
304 /// It is a helper function to write a graph to the given output
305 /// file. It gives back a GraphWriter object and this object
306 /// can write more maps, labeled nodes and edges and attributes.
307 /// \warning Do not forget to call the \c run() function.
309 /// \param fn The filename.
310 /// \param g The graph.
311 template <typename Graph>
312 GraphWriter<Graph> graphWriter(const std::string& fn, const Graph &g) {
313 return GraphWriter<Graph>(fn, g);
316 /// \brief The undirected graph writer class.
318 /// The \c UndirGraphWriter class provides the undir graph output. To write
319 /// a graph you should first give writing commands to the writer. You can
320 /// declare write command as \c NodeMap, \c EdgeMap or \c UndirEdgeMap
321 /// writing and labeled Node, Edge or UndirEdge writing.
324 /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph);
327 /// The \c writeNodeMap() function declares a \c NodeMap writing
328 /// command in the \c UndirGraphWriter. You should give as parameter
329 /// the name of the map and the map object. The NodeMap writing
330 /// command with name "id" should write a unique map because it
331 /// is regarded as ID map.
334 /// IdMap<UndirListGraph, Node> nodeIdMap;
335 /// writer.writeNodeMap("id", nodeIdMap);
337 /// writer.writeNodeMap("coords", coords);
338 /// writer.writeNodeMap("color", colorMap);
341 /// With the \c writeUndirEdgeMap() member function you can give an
342 /// undirected edge map writing command similar to the NodeMaps.
345 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
346 /// edgeDescMap(graph);
347 /// writer.writeUndirEdgeMap("descriptor", edgeDescMap);
349 /// writer.writeUndirEdgeMap("weight", weightMap);
350 /// writer.writeUndirEdgeMap("label", labelMap);
353 /// The EdgeMap handling is just a syntactical sugar. It writes
354 /// two undirected edge map with '+' and '-' prefix in the name.
357 /// writer.writeEdgeMap("capacity", capacityMap);
361 /// With \c writeNode() and \c writeUndirEdge() functions you can
362 /// designate nodes and undirected edges in the graph. For example, you can
363 /// write out the source and target of the graph.
366 /// writer.writeNode("source", sourceNode);
367 /// writer.writeNode("target", targetNode);
369 /// writer.writeUndirEdge("observed", undirEdge);
372 /// After you give all write commands you must call the \c run() member
373 /// function, which executes all the writing commands.
379 /// \see DefaultWriterTraits
380 /// \see QuotedStringWriter
382 /// \see DescriptorMap
383 /// \see \ref GraphWriter
384 /// \see \ref graph-io-page
385 /// \author Balazs Dezso
386 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
387 class UndirGraphWriter {
390 typedef _Graph Graph;
391 typedef typename Graph::Node Node;
392 typedef typename Graph::Edge Edge;
393 typedef typename Graph::UndirEdge UndirEdge;
395 typedef _WriterTraits WriterTraits;
397 /// \brief Construct a new UndirGraphWriter.
399 /// Construct a new UndirGraphWriter. It writes the given graph
400 /// to the given stream.
401 UndirGraphWriter(std::ostream& _os, const Graph& _graph)
402 : writer(new LemonWriter(_os)), own_writer(true),
403 nodeset_writer(*writer, _graph, std::string()),
404 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
405 node_writer(*writer, nodeset_writer, std::string()),
406 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
407 attribute_writer(*writer, std::string()) {}
409 /// \brief Construct a new UndirGraphWriter.
411 /// Construct a new UndirGraphWriter. It writes the given graph
412 /// to the given file.
413 UndirGraphWriter(const std::string& _filename, const Graph& _graph)
414 : writer(new LemonWriter(_filename)), own_writer(true),
415 nodeset_writer(*writer, _graph, std::string()),
416 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
417 node_writer(*writer, nodeset_writer, std::string()),
418 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
419 attribute_writer(*writer, std::string()) {}
421 /// \brief Construct a new UndirGraphWriter.
423 /// Construct a new UndirGraphWriter. It writes the given graph
424 /// to given LemonReader.
425 UndirGraphWriter(LemonWriter& _writer, const Graph& _graph)
426 : writer(_writer), own_writer(false),
427 nodeset_writer(*writer, _graph, std::string()),
428 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
429 node_writer(*writer, nodeset_writer, std::string()),
430 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
431 attribute_writer(*writer, std::string()) {}
433 /// \brief Destruct the graph writer.
435 /// Destruct the graph writer.
436 ~UndirGraphWriter() {
441 /// \brief Issue a new node map writing command to the writer.
443 /// This function issues a new <i> node map writing command</i> to the writer.
444 template <typename Map>
445 UndirGraphWriter& writeNodeMap(std::string name, const Map& map) {
446 nodeset_writer.writeNodeMap(name, map);
450 /// \brief Issue a new node map writing command to the writer.
452 /// This function issues a new <i> node map writing command</i> to the writer.
453 template <typename Writer, typename Map>
454 UndirGraphWriter& writeNodeMap(std::string name, const Map& map,
455 const Writer& writer = Writer()) {
456 nodeset_writer.writeNodeMap(name, map, writer);
460 /// \brief Issue a new edge map writing command to the writer.
462 /// This function issues a new <i> edge map writing command</i> to the writer.
463 template <typename Map>
464 UndirGraphWriter& writeEdgeMap(std::string name, const Map& map) {
465 undir_edgeset_writer.writeEdgeMap(name, map);
469 /// \brief Issue a new edge map writing command to the writer.
471 /// This function issues a new <i> edge map writing command</i> to the writer.
472 template <typename Writer, typename Map>
473 UndirGraphWriter& writeEdgeMap(std::string name, const Map& map,
474 const Writer& writer = Writer()) {
475 undir_edgeset_writer.writeEdgeMap(name, map, writer);
479 /// \brief Issue a new undirected edge map writing command to the writer.
481 /// This function issues a new <i> undirected edge map writing
482 /// command</i> to the writer.
483 template <typename Map>
484 UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map) {
485 undir_edgeset_writer.writeUndirEdgeMap(name, map);
489 /// \brief Issue a new undirected edge map writing command to the writer.
491 /// This function issues a new <i> undirected edge map writing
492 /// command</i> to the writer.
493 template <typename Writer, typename Map>
494 UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map,
495 const Writer& writer = Writer()) {
496 undir_edgeset_writer.writeUndirEdgeMap(name, map, writer);
500 /// \brief Issue a new labeled node writer to the writer.
502 /// This function issues a new <i> labeled node writing
503 /// command</i> to the writer.
504 UndirGraphWriter& writeNode(std::string name, const Node& node) {
505 node_writer.writeNode(name, node);
509 /// \brief Issue a new labeled edge writer to the writer.
511 /// This function issues a new <i> labeled edge writing
512 /// command</i> to the writer.
513 UndirGraphWriter& writeEdge(std::string name, const Edge& edge) {
514 undir_edge_writer.writeEdge(name, edge);
517 /// \brief Issue a new labeled undirected edge writing command to
520 /// Issue a new <i>labeled undirected edge writing command</i> to
522 UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) {
523 undir_edge_writer.writeUndirEdge(name, edge);
526 /// \brief Issue a new attribute writing command.
528 /// This function issues a new <i> attribute writing
529 /// command</i> to the writer.
530 template <typename Value>
531 UndirGraphWriter& writeAttribute(std::string name, const Value& value) {
532 attribute_writer.writeAttribute(name, value);
536 /// \brief Issue a new attribute writing command.
538 /// This function issues a new <i> attribute writing
539 /// command</i> to the writer.
540 template <typename Writer, typename Value>
541 UndirGraphWriter& writeAttribute(std::string name, const Value& value,
542 const Writer& writer) {
543 attribute_writer.writeAttribute<Writer>(name, value, writer);
547 /// \brief Conversion operator to LemonWriter.
549 /// Conversion operator to LemonWriter. It makes possible
550 /// to access the encapsulated \e LemonWriter, this way
551 /// you can attach to this writer new instances of
552 /// \e LemonWriter::SectionWriter.
553 operator LemonWriter&() {
557 /// \brief Executes the writing commands.
559 /// Executes the writing commands.
564 /// \brief Write the id of the given node.
566 /// It writes the id of the given node. If there was written an "id"
567 /// named node map then it will write the map value belonging to the node.
568 void writeId(std::ostream& os, const Node& item) const {
569 nodeset_writer.writeId(os, item);
572 /// \brief Write the id of the given edge.
574 /// It writes the id of the given edge. If there was written an "id"
575 /// named edge map then it will write the map value belonging to the edge.
576 void writeId(std::ostream& os, const Edge& item) const {
577 undir_edgeset_writer.writeId(os, item);
580 /// \brief Write the id of the given undirected edge.
582 /// It writes the id of the given undirected edge. If there was written
583 /// an "id" named edge map then it will write the map value belonging to
585 void writeId(std::ostream& os, const UndirEdge& item) const {
586 undir_edgeset_writer.writeId(os, item);
595 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
596 UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer;
598 NodeWriter<Graph> node_writer;
599 UndirEdgeWriter<Graph> undir_edge_writer;
601 AttributeWriter<WriterTraits> attribute_writer;
604 /// \brief Write an undirected graph to the output.
606 /// It is a helper function to write an undirected graph to the given output
607 /// stream. It gives back an UndirGraphWriter object and this object
608 /// can write more maps, labeled nodes and edges and attributes.
609 /// \warning Do not forget to call the \c run() function.
611 /// \param os The output stream.
612 /// \param g The graph.
613 template <typename Graph>
614 UndirGraphWriter<Graph> undirGraphWriter(std::ostream& os, const Graph &g) {
615 return UndirGraphWriter<Graph>(os, g);
618 /// \brief Write an undirected graph to the output.
620 /// It is a helper function to write an undirected graph to the given output
621 /// file. It gives back an UndirGraphWriter object and this object
622 /// can write more maps, labeled nodes, edges, undirected edges and
625 /// \warning Do not forget to call the \c run() function.
627 /// \param fn The output file.
628 /// \param g The graph.
629 template <typename Graph>
630 UndirGraphWriter<Graph> undirGraphWriter(const std::string& fn,
632 return UndirGraphWriter<Graph>(fn, g);