vmap.h: Enables one to create maps with a virtual base class.
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".
43 /// If you don't need very sophisticated
44 /// behaviour then you can use the versions of the public function
45 /// \ref writeGraph() to output a graph (or a max flow instance etc).
48 /// you should first give writing commands to the writer. You can declare
49 /// write commands as \c NodeMap or \c EdgeMap writing and labeled Node and
53 /// GraphWriter<ListGraph> writer(std::cout, graph);
56 /// The \c writeNodeMap() function declares a \c NodeMap writing
57 /// command in the \c GraphWriter. You should give as parameter
58 /// the name of the map and the map object. The NodeMap writing
59 /// command with name "label" should write a unique map because it
60 /// is regarded as label map (such a map is essential if the graph has edges).
63 /// IdMap<ListGraph, Node> nodeLabelMap;
64 /// writer.writeNodeMap("label", nodeLabelMap);
66 /// writer.writeNodeMap("coords", coords);
67 /// writer.writeNodeMap("color", colorMap);
70 /// With the \c writeEdgeMap() member function you can give an edge map
71 /// writing command similar to the NodeMaps.
74 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
75 /// edgeDescMap(graph);
76 /// writer.writeEdgeMap("descriptor", edgeDescMap);
78 /// writer.writeEdgeMap("weight", weightMap);
79 /// writer.writeEdgeMap("label", labelMap);
82 /// With \c writeNode() and \c writeEdge() functions you can
83 /// point out Nodes and Edges in the graph. For example, you can
84 /// write out the source and target of a maximum flow instance.
87 /// writer.writeNode("source", sourceNode);
88 /// writer.writeNode("target", targetNode);
90 /// writer.writeEdge("observed", edge);
93 /// After you give all write commands you must call the \c run() member
94 /// function, which executes all the writing commands.
100 /// \see DefaultWriterTraits
101 /// \see QuotedStringWriter
103 /// \see DescriptorMap
104 /// \see \ref GraphReader
105 /// \see \ref graph-io-page
106 /// \author Balazs Dezso
107 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
111 typedef _Graph Graph;
112 typedef typename Graph::Node Node;
113 typedef typename Graph::Edge Edge;
115 typedef _WriterTraits WriterTraits;
117 /// \brief Construct a new GraphWriter.
119 /// This function constructs a new GraphWriter to write the given graph
120 /// to the given stream.
121 GraphWriter(std::ostream& _os, const Graph& _graph)
122 : writer(new LemonWriter(_os)), own_writer(true),
123 nodeset_writer(*writer, _graph, std::string()),
124 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
125 node_writer(*writer, nodeset_writer, std::string()),
126 edge_writer(*writer, edgeset_writer, std::string()),
127 attribute_writer(*writer, std::string()) {}
129 /// \brief Construct a new GraphWriter.
131 /// This function constructs a new GraphWriter to write the given graph
132 /// to the given file.
133 GraphWriter(const std::string& _filename, const Graph& _graph)
134 : writer(new LemonWriter(_filename)), own_writer(true),
135 nodeset_writer(*writer, _graph, std::string()),
136 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
137 node_writer(*writer, nodeset_writer, std::string()),
138 edge_writer(*writer, edgeset_writer, std::string()),
139 attribute_writer(*writer, std::string()) {}
141 /// \brief Construct a new GraphWriter.
143 /// This function constructs a new GraphWriter to write the given graph
144 /// to the given LemonReader.
145 GraphWriter(LemonWriter& _writer, const Graph& _graph)
146 : writer(_writer), own_writer(false),
147 nodeset_writer(*writer, _graph, std::string()),
148 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
149 node_writer(*writer, nodeset_writer, std::string()),
150 edge_writer(*writer, edgeset_writer, std::string()),
151 attribute_writer(*writer, std::string()) {}
153 /// \brief Destruct the graph writer.
155 /// This function destructs the graph writer.
161 /// \brief Issue a new node map writing command for the writer.
163 /// This function issues a new <i> node map writing command</i> to the writer.
164 template <typename Map>
165 GraphWriter& writeNodeMap(std::string name, const Map& map) {
166 nodeset_writer.writeNodeMap(name, map);
171 /// \brief Issue a new node map writing command for the writer.
173 /// This function issues a new <i> node map writing command</i> to the writer.
174 template <typename Writer, typename Map>
175 GraphWriter& writeNodeMap(std::string name, const Map& map,
176 const Writer& writer = Writer()) {
177 nodeset_writer.writeNodeMap(name, map, writer);
182 /// \brief Issue a new edge map writing command for the writer.
184 /// This function issues a new <i> edge map writing command</i> to the writer.
185 template <typename Map>
186 GraphWriter& writeEdgeMap(std::string name, const Map& map) {
187 edgeset_writer.writeEdgeMap(name, map);
192 /// \brief Issue a new edge map writing command for the writer.
194 /// This function issues a new <i> edge map writing command</i> to the writer.
195 template <typename Writer, typename Map>
196 GraphWriter& writeEdgeMap(std::string name, const Map& map,
197 const Writer& writer = Writer()) {
198 edgeset_writer.writeEdgeMap(name, map, writer);
202 /// \brief Issue a new labeled node writing command to the writer.
204 /// This function issues a new <i> labeled node writing command</i>
206 GraphWriter& writeNode(std::string name, const Node& node) {
207 node_writer.writeNode(name, node);
211 /// \brief Issue a new labeled edge writing command to the writer.
213 /// This function issues a new <i> labeled edge writing command</i>
215 GraphWriter& writeEdge(std::string name, const Edge& edge) {
216 edge_writer.writeEdge(name, edge);
219 /// \brief Issue a new attribute writing command.
221 /// This function issues a new <i> attribute writing command</i>
223 template <typename Value>
224 GraphWriter& writeAttribute(std::string name, const Value& value) {
225 attribute_writer.writeAttribute(name, value);
229 /// \brief Issue a new attribute writing command.
231 /// This function issues a new <i> attribute writing command</i>
233 template <typename Writer, typename Value>
234 GraphWriter& writeAttribute(std::string name, const Value& value,
235 const Writer& writer) {
236 attribute_writer.writeAttribute<Writer>(name, value, writer);
240 /// \brief Conversion operator to LemonWriter.
242 /// Conversion operator to LemonWriter. It makes possible
243 /// to access the encapsulated \e LemonWriter, this way
244 /// you can attach to this writer new instances of
245 /// \e LemonWriter::SectionWriter. For more details see
246 /// the \ref rwbackground "Background of Reading and Writing".
247 operator LemonWriter&() {
251 /// \brief Executes the writing commands.
253 /// Executes the writing commands.
258 /// \brief Write the label of the given node.
260 /// It writes the label of the given node. If there was written an "label"
261 /// named node map then it will write the map value belonging to the node.
262 void writeLabel(std::ostream& os, const Node& item) const {
263 nodeset_writer.writeLabel(os, item);
266 /// \brief Write the label of the given edge.
268 /// It writes the label of the given edge. If there was written an "label"
269 /// named edge map then it will write the map value belonging to the edge.
270 void writeLabel(std::ostream& os, const Edge& item) const {
271 edgeset_writer.writeLabel(os, item);
279 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
280 EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
282 NodeWriter<Graph> node_writer;
283 EdgeWriter<Graph> edge_writer;
285 AttributeWriter<WriterTraits> attribute_writer;
290 /// \brief Write a graph to the output.
292 /// It is a helper function to write a graph to the given output
293 /// stream. It gives back a GraphWriter object and this object
294 /// can write more maps, labeled nodes and edges and attributes.
295 /// \warning Do not forget to call the \c run() function.
297 /// \param os The output stream.
298 /// \param g The graph.
299 template <typename Graph>
300 GraphWriter<Graph> graphWriter(std::ostream& os, const Graph &g) {
301 return GraphWriter<Graph>(os, g);
304 /// \brief Write a graph to the output.
306 /// It is a helper function to write a graph to the given output
307 /// file. It gives back a GraphWriter object and this object
308 /// can write more maps, labeled nodes and edges and attributes.
309 /// \warning Do not forget to call the \c run() function.
311 /// \param fn The filename.
312 /// \param g The graph.
313 template <typename Graph>
314 GraphWriter<Graph> graphWriter(const std::string& fn, const Graph &g) {
315 return GraphWriter<Graph>(fn, g);
318 /// \brief The undirected graph writer class.
320 /// The \c UGraphWriter class provides the ugraph output. To write
321 /// a graph you should first give writing commands to the writer. You can
322 /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap
323 /// writing and labeled Node, Edge or UEdge writing.
326 /// UGraphWriter<ListUGraph> writer(std::cout, graph);
329 /// The \c writeNodeMap() function declares a \c NodeMap writing
330 /// command in the \c UGraphWriter. You should give as parameter
331 /// the name of the map and the map object. The NodeMap writing
332 /// command with name "label" should write a unique map because it
333 /// is regarded as label map.
336 /// IdMap<ListUGraph, Node> nodeLabelMap;
337 /// writer.writeNodeMap("label", nodeLabelMap);
339 /// writer.writeNodeMap("coords", coords);
340 /// writer.writeNodeMap("color", colorMap);
343 /// With the \c writeUEdgeMap() member function you can give an
344 /// undirected edge map writing command similar to the NodeMaps.
347 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
348 /// edgeDescMap(graph);
349 /// writer.writeUEdgeMap("descriptor", edgeDescMap);
351 /// writer.writeUEdgeMap("weight", weightMap);
352 /// writer.writeUEdgeMap("label", labelMap);
355 /// The EdgeMap handling is just a syntactical sugar. It writes
356 /// two undirected edge map with '+' and '-' prefix in the name.
359 /// writer.writeEdgeMap("capacity", capacityMap);
363 /// With \c writeNode() and \c writeUEdge() functions you can
364 /// designate nodes and undirected edges in the graph. For example, you can
365 /// write out the source and target of the graph.
368 /// writer.writeNode("source", sourceNode);
369 /// writer.writeNode("target", targetNode);
371 /// writer.writeUEdge("observed", uEdge);
374 /// After you give all write commands you must call the \c run() member
375 /// function, which executes all the writing commands.
381 /// \see DefaultWriterTraits
382 /// \see QuotedStringWriter
384 /// \see DescriptorMap
385 /// \see \ref GraphWriter
386 /// \see \ref graph-io-page
387 /// \author Balazs Dezso
388 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
392 typedef _Graph Graph;
393 typedef typename Graph::Node Node;
394 typedef typename Graph::Edge Edge;
395 typedef typename Graph::UEdge UEdge;
397 typedef _WriterTraits WriterTraits;
399 /// \brief Construct a new UGraphWriter.
401 /// Construct a new UGraphWriter. It writes the given graph
402 /// to the given stream.
403 UGraphWriter(std::ostream& _os, const Graph& _graph)
404 : writer(new LemonWriter(_os)), own_writer(true),
405 nodeset_writer(*writer, _graph, std::string()),
406 u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
407 node_writer(*writer, nodeset_writer, std::string()),
408 u_edge_writer(*writer, u_edgeset_writer, std::string()),
409 attribute_writer(*writer, std::string()) {}
411 /// \brief Construct a new UGraphWriter.
413 /// Construct a new UGraphWriter. It writes the given graph
414 /// to the given file.
415 UGraphWriter(const std::string& _filename, const Graph& _graph)
416 : writer(new LemonWriter(_filename)), own_writer(true),
417 nodeset_writer(*writer, _graph, std::string()),
418 u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
419 node_writer(*writer, nodeset_writer, std::string()),
420 u_edge_writer(*writer, u_edgeset_writer, std::string()),
421 attribute_writer(*writer, std::string()) {}
423 /// \brief Construct a new UGraphWriter.
425 /// Construct a new UGraphWriter. It writes the given graph
426 /// to given LemonReader.
427 UGraphWriter(LemonWriter& _writer, const Graph& _graph)
428 : writer(_writer), own_writer(false),
429 nodeset_writer(*writer, _graph, std::string()),
430 u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
431 node_writer(*writer, nodeset_writer, std::string()),
432 u_edge_writer(*writer, u_edgeset_writer, std::string()),
433 attribute_writer(*writer, std::string()) {}
435 /// \brief Destruct the graph writer.
437 /// Destruct the graph writer.
443 /// \brief Issue a new node map writing command to the writer.
445 /// This function issues a new <i> node map writing command</i> to the writer.
446 template <typename Map>
447 UGraphWriter& writeNodeMap(std::string name, const Map& map) {
448 nodeset_writer.writeNodeMap(name, map);
452 /// \brief Issue a new node map writing command to the writer.
454 /// This function issues a new <i> node map writing command</i> to the writer.
455 template <typename Writer, typename Map>
456 UGraphWriter& writeNodeMap(std::string name, const Map& map,
457 const Writer& writer = Writer()) {
458 nodeset_writer.writeNodeMap(name, map, writer);
462 /// \brief Issue a new edge map writing command to the writer.
464 /// This function issues a new <i> edge map writing command</i> to the writer.
465 template <typename Map>
466 UGraphWriter& writeEdgeMap(std::string name, const Map& map) {
467 u_edgeset_writer.writeEdgeMap(name, map);
471 /// \brief Issue a new edge map writing command to the writer.
473 /// This function issues a new <i> edge map writing command</i> to the writer.
474 template <typename Writer, typename Map>
475 UGraphWriter& writeEdgeMap(std::string name, const Map& map,
476 const Writer& writer = Writer()) {
477 u_edgeset_writer.writeEdgeMap(name, map, writer);
481 /// \brief Issue a new undirected edge map writing command to the writer.
483 /// This function issues a new <i> undirected edge map writing
484 /// command</i> to the writer.
485 template <typename Map>
486 UGraphWriter& writeUEdgeMap(std::string name, const Map& map) {
487 u_edgeset_writer.writeUEdgeMap(name, map);
491 /// \brief Issue a new undirected edge map writing command to the writer.
493 /// This function issues a new <i> undirected edge map writing
494 /// command</i> to the writer.
495 template <typename Writer, typename Map>
496 UGraphWriter& writeUEdgeMap(std::string name, const Map& map,
497 const Writer& writer = Writer()) {
498 u_edgeset_writer.writeUEdgeMap(name, map, writer);
502 /// \brief Issue a new labeled node writer to the writer.
504 /// This function issues a new <i> labeled node writing
505 /// command</i> to the writer.
506 UGraphWriter& writeNode(std::string name, const Node& node) {
507 node_writer.writeNode(name, node);
511 /// \brief Issue a new labeled edge writer to the writer.
513 /// This function issues a new <i> labeled edge writing
514 /// command</i> to the writer.
515 UGraphWriter& writeEdge(std::string name, const Edge& edge) {
516 u_edge_writer.writeEdge(name, edge);
519 /// \brief Issue a new labeled undirected edge writing command to
522 /// Issue a new <i>labeled undirected edge writing command</i> to
524 UGraphWriter& writeUEdge(std::string name, const UEdge& edge) {
525 u_edge_writer.writeUEdge(name, edge);
528 /// \brief Issue a new attribute writing command.
530 /// This function issues a new <i> attribute writing
531 /// command</i> to the writer.
532 template <typename Value>
533 UGraphWriter& writeAttribute(std::string name, const Value& value) {
534 attribute_writer.writeAttribute(name, value);
538 /// \brief Issue a new attribute writing command.
540 /// This function issues a new <i> attribute writing
541 /// command</i> to the writer.
542 template <typename Writer, typename Value>
543 UGraphWriter& writeAttribute(std::string name, const Value& value,
544 const Writer& writer) {
545 attribute_writer.writeAttribute<Writer>(name, value, writer);
549 /// \brief Conversion operator to LemonWriter.
551 /// Conversion operator to LemonWriter. It makes possible
552 /// to access the encapsulated \e LemonWriter, this way
553 /// you can attach to this writer new instances of
554 /// \e LemonWriter::SectionWriter.
555 operator LemonWriter&() {
559 /// \brief Executes the writing commands.
561 /// Executes the writing commands.
566 /// \brief Write the label of the given node.
568 /// It writes the label of the given node. If there was written an "label"
569 /// named node map then it will write the map value belonging to the node.
570 void writeLabel(std::ostream& os, const Node& item) const {
571 nodeset_writer.writeLabel(os, item);
574 /// \brief Write the label of the given edge.
576 /// It writes the label of the given edge. If there was written an "label"
577 /// named edge map then it will write the map value belonging to the edge.
578 void writeLabel(std::ostream& os, const Edge& item) const {
579 u_edgeset_writer.writeLabel(os, item);
582 /// \brief Write the label of the given undirected edge.
584 /// It writes the label of the given undirected edge. If there was written
585 /// an "label" named edge map then it will write the map value belonging to
587 void writeLabel(std::ostream& os, const UEdge& item) const {
588 u_edgeset_writer.writeLabel(os, item);
597 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
598 UEdgeSetWriter<Graph, WriterTraits> u_edgeset_writer;
600 NodeWriter<Graph> node_writer;
601 UEdgeWriter<Graph> u_edge_writer;
603 AttributeWriter<WriterTraits> attribute_writer;
606 /// \brief Write an undirected graph to the output.
608 /// It is a helper function to write an undirected graph to the given output
609 /// stream. It gives back an UGraphWriter object and this object
610 /// can write more maps, labeled nodes and edges and attributes.
611 /// \warning Do not forget to call the \c run() function.
613 /// \param os The output stream.
614 /// \param g The graph.
615 template <typename Graph>
616 UGraphWriter<Graph> uGraphWriter(std::ostream& os, const Graph &g) {
617 return UGraphWriter<Graph>(os, g);
620 /// \brief Write an undirected graph to the output.
622 /// It is a helper function to write an undirected graph to the given output
623 /// file. It gives back an UGraphWriter object and this object
624 /// can write more maps, labeled nodes, edges, undirected edges and
627 /// \warning Do not forget to call the \c run() function.
629 /// \param fn The output file.
630 /// \param g The graph.
631 template <typename Graph>
632 UGraphWriter<Graph> uGraphWriter(const std::string& fn,
634 return UGraphWriter<Graph>(fn, g);