lemon/graph_writer.h
author hegyi
Mon, 21 Nov 2005 18:03:20 +0000
changeset 1823 cb082cdf3667
parent 1540 7d028a73d7f2
child 1875 98698b69a902
permissions -rw-r--r--
NewMapWin has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.
     1 /* -*- C++ -*-
     2  * lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     6  *
     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.
    10  *
    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
    13  * purpose.
    14  *
    15  */
    16 
    17 ///\ingroup io_group
    18 ///\file
    19 ///\brief Lemon Graph Format writer.
    20 ///
    21 
    22 #ifndef LEMON_GRAPH_WRITER_H
    23 #define LEMON_GRAPH_WRITER_H
    24 
    25 #include <iostream>
    26 
    27 #include <lemon/error.h>
    28 #include <lemon/lemon_writer.h>
    29 
    30 namespace lemon {
    31 
    32   /// \addtogroup io_group
    33   /// @{
    34 
    35   /// \brief The graph writer class.
    36   ///
    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".
    40   ///
    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).
    44   ///
    45   /// To write a graph
    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
    48   /// Edge writing.
    49   ///
    50   /// \code
    51   /// GraphWriter<ListGraph> writer(std::cout, graph);
    52   /// \endcode
    53   ///
    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).
    59   ///
    60   /// \code
    61   /// IdMap<ListGraph, Node> nodeIdMap;
    62   /// writer.writeNodeMap("id", nodeIdMap);
    63   ///
    64   /// writer.writeNodeMap("coords", coords);
    65   /// writer.writeNodeMap("color", colorMap);
    66   /// \endcode
    67   ///
    68   /// With the \c writeEdgeMap() member function you can give an edge map
    69   /// writing command similar to the NodeMaps.
    70   ///
    71   /// \code
    72   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
    73   ///   edgeDescMap(graph);
    74   /// writer.writeEdgeMap("descriptor", edgeDescMap);
    75   ///
    76   /// writer.writeEdgeMap("weight", weightMap);
    77   /// writer.writeEdgeMap("label", labelMap);
    78   /// \endcode
    79   ///
    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.
    83   ///
    84   /// \code
    85   /// writer.writeNode("source", sourceNode);
    86   /// writer.writeNode("target", targetNode);
    87   ///
    88   /// writer.writeEdge("observed", edge);
    89   /// \endcode
    90   ///
    91   /// After you give all write commands you must call the \c run() member
    92   /// function, which executes all the writing commands.
    93   ///
    94   /// \code
    95   /// writer.run();
    96   /// \endcode
    97   ///
    98   /// \see DefaultWriterTraits
    99   /// \see QuotedStringWriter
   100   /// \see IdMap
   101   /// \see DescriptorMap
   102   /// \see \ref GraphReader
   103   /// \see \ref graph-io-page
   104   /// \author Balazs Dezso
   105   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   106   class GraphWriter {
   107   public:
   108     
   109     typedef _Graph Graph;
   110     typedef typename Graph::Node Node;
   111     typedef typename Graph::Edge Edge;
   112 
   113     typedef _WriterTraits WriterTraits;
   114 
   115     /// \brief Construct a new GraphWriter.
   116     ///
   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()) {}
   126 
   127     /// \brief Construct a new GraphWriter.
   128     ///
   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()) {}
   138 
   139     /// \brief Construct a new GraphWriter.
   140     ///
   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()) {}
   150 
   151     /// \brief Destruct the graph writer.
   152     ///
   153     /// This function destructs the graph writer.
   154     ~GraphWriter() {
   155       if (own_writer) 
   156 	delete writer;
   157     }
   158 
   159     /// \brief Issue a new node map writing command for the writer.
   160     ///
   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);
   165       return *this;
   166     }
   167 
   168 
   169     /// \brief Issue a new node map writing command for the writer.
   170     ///
   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);
   176       return *this;
   177     }
   178 
   179 
   180     /// \brief Issue a new edge map writing command for the writer.
   181     ///
   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);
   186       return *this;
   187     }
   188 
   189 
   190     /// \brief Issue a new edge map writing command for the writer.
   191     ///
   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);
   197       return *this;
   198     }
   199 
   200     /// \brief Issue a new labeled node writing command to the writer.
   201     ///
   202     /// This function issues a new <i> labeled node writing command</i> 
   203     /// to the writer.
   204     GraphWriter& writeNode(std::string name, const Node& node) {
   205       node_writer.writeNode(name, node);
   206       return *this;
   207     }
   208 
   209     /// \brief Issue a new labeled edge writing command to the writer.
   210     ///
   211     /// This function issues a new <i> labeled edge writing command</i> 
   212     /// to the writer.
   213     GraphWriter& writeEdge(std::string name, const Edge& edge) {
   214       edge_writer.writeEdge(name, edge);
   215     }
   216 
   217     /// \brief Issue a new attribute writing command.
   218     ///
   219     /// This function issues a new <i> attribute writing command</i> 
   220     /// to the writer.
   221     template <typename Value>
   222     GraphWriter& writeAttribute(std::string name, const Value& value) {
   223       attribute_writer.writeAttribute(name, value);
   224       return *this;
   225     }
   226     
   227     /// \brief Issue a new attribute writing command.
   228     ///
   229     /// This function issues a new <i> attribute writing command</i> 
   230     /// to the writer.
   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);
   235       return *this;
   236     }
   237 
   238     /// \brief Conversion operator to LemonWriter.
   239     ///
   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&() {
   246       return *writer;
   247     }
   248 
   249     /// \brief Executes the writing commands.
   250     ///
   251     /// Executes the writing commands.
   252     void run() {
   253       writer->run();
   254     }
   255 
   256     /// \brief Write the id of the given node.
   257     ///
   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);
   262     } 
   263 
   264     /// \brief Write the id of the given edge.
   265     ///
   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);
   270     } 
   271 
   272   private:
   273 
   274     LemonWriter* writer;
   275     bool own_writer;
   276 
   277     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   278     EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
   279 
   280     NodeWriter<Graph> node_writer;
   281     EdgeWriter<Graph> edge_writer;
   282     
   283     AttributeWriter<WriterTraits> attribute_writer;
   284   };
   285 
   286 
   287 
   288   /// \brief Write a graph to the output.
   289   ///
   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.
   294   ///
   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);
   300   }
   301 
   302   /// \brief Write a graph to the output.
   303   ///
   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.
   308   ///
   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);
   314   }
   315 
   316   /// \brief The undirected graph writer class.
   317   ///
   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.
   322   ///
   323   /// \code
   324   /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph);
   325   /// \endcode
   326   ///
   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.
   332   ///
   333   /// \code
   334   /// IdMap<UndirListGraph, Node> nodeIdMap;
   335   /// writer.writeNodeMap("id", nodeIdMap);
   336   ///
   337   /// writer.writeNodeMap("coords", coords);
   338   /// writer.writeNodeMap("color", colorMap);
   339   /// \endcode
   340   ///
   341   /// With the \c writeUndirEdgeMap() member function you can give an 
   342   /// undirected edge map writing command similar to the NodeMaps.
   343   ///
   344   /// \code
   345   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
   346   ///   edgeDescMap(graph);
   347   /// writer.writeUndirEdgeMap("descriptor", edgeDescMap);
   348   ///
   349   /// writer.writeUndirEdgeMap("weight", weightMap);
   350   /// writer.writeUndirEdgeMap("label", labelMap);
   351   /// \endcode
   352   /// 
   353   /// The EdgeMap handling is just a syntactical sugar. It writes
   354   /// two undirected edge map with '+' and '-' prefix in the name.
   355   ///
   356   /// \code
   357   /// writer.writeEdgeMap("capacity", capacityMap);
   358   /// \endcode
   359   ///
   360   ///
   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.
   364   ///
   365   /// \code
   366   /// writer.writeNode("source", sourceNode);
   367   /// writer.writeNode("target", targetNode);
   368   ///
   369   /// writer.writeUndirEdge("observed", undirEdge);
   370   /// \endcode
   371   ///
   372   /// After you give all write commands you must call the \c run() member
   373   /// function, which executes all the writing commands.
   374   ///
   375   /// \code
   376   /// writer.run();
   377   /// \endcode
   378   ///
   379   /// \see DefaultWriterTraits
   380   /// \see QuotedStringWriter
   381   /// \see IdMap
   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 {
   388   public:
   389     
   390     typedef _Graph Graph;
   391     typedef typename Graph::Node Node;
   392     typedef typename Graph::Edge Edge;
   393     typedef typename Graph::UndirEdge UndirEdge;
   394 
   395     typedef _WriterTraits WriterTraits;
   396 
   397     /// \brief Construct a new UndirGraphWriter.
   398     ///
   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()) {}
   408 
   409     /// \brief Construct a new UndirGraphWriter.
   410     ///
   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()) {}
   420 
   421     /// \brief Construct a new UndirGraphWriter.
   422     ///
   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()) {}
   432 
   433     /// \brief Destruct the graph writer.
   434     ///
   435     /// Destruct the graph writer.
   436     ~UndirGraphWriter() {
   437       if (own_writer) 
   438 	delete writer;
   439     }
   440 
   441     /// \brief Issue a new node map writing command to the writer.
   442     ///
   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);
   447       return *this;
   448     }
   449 
   450     /// \brief Issue a new node map writing command to the writer.
   451     ///
   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);
   457       return *this;
   458     }
   459 
   460     /// \brief Issue a new edge map writing command to the writer.
   461     ///
   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);
   466       return *this;
   467     }
   468 
   469     /// \brief Issue a new edge map writing command to the writer.
   470     ///
   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);
   476       return *this;
   477     }
   478 
   479     /// \brief Issue a new undirected edge map writing command to the writer.
   480     ///
   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);
   486       return *this;
   487     }
   488 
   489     /// \brief Issue a new undirected edge map writing command to the writer.
   490     ///
   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);
   497       return *this;
   498     }
   499 
   500     /// \brief Issue a new labeled node writer to the writer.
   501     ///
   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);
   506       return *this;
   507     }
   508 
   509     /// \brief Issue a new labeled edge writer to the writer.
   510     ///
   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);
   515     }
   516 
   517     /// \brief Issue a new labeled undirected edge writing command to
   518     /// the writer.
   519     ///
   520     /// Issue a new <i>labeled undirected edge writing command</i> to
   521     /// the writer.
   522     UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) {
   523       undir_edge_writer.writeUndirEdge(name, edge);
   524     }
   525 
   526     /// \brief Issue a new attribute writing command.
   527     ///
   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);
   533       return *this;
   534     }
   535     
   536     /// \brief Issue a new attribute writing command.
   537     ///
   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);
   544       return *this;
   545     }
   546 
   547     /// \brief Conversion operator to LemonWriter.
   548     ///
   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&() {
   554       return *writer;
   555     }
   556 
   557     /// \brief Executes the writing commands.
   558     ///
   559     /// Executes the writing commands.
   560     void run() {
   561       writer->run();
   562     }
   563 
   564     /// \brief Write the id of the given node.
   565     ///
   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);
   570     } 
   571 
   572     /// \brief Write the id of the given edge.
   573     ///
   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);
   578     } 
   579 
   580     /// \brief Write the id of the given undirected edge.
   581     ///
   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 
   584     /// the edge.
   585     void writeId(std::ostream& os, const UndirEdge& item) const {
   586       undir_edgeset_writer.writeId(os, item);
   587     } 
   588 
   589 
   590   private:
   591 
   592     LemonWriter* writer;
   593     bool own_writer;
   594 
   595     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   596     UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer;
   597 
   598     NodeWriter<Graph> node_writer;
   599     UndirEdgeWriter<Graph> undir_edge_writer;
   600     
   601     AttributeWriter<WriterTraits> attribute_writer;
   602   };
   603 
   604   /// \brief Write an undirected graph to the output.
   605   ///
   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.
   610   ///
   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);
   616   }
   617 
   618   /// \brief Write an undirected graph to the output.
   619   ///
   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 
   623   /// attributes.
   624   ///
   625   /// \warning Do not forget to call the \c run() function.
   626   ///
   627   /// \param fn The output file.
   628   /// \param g The graph.
   629   template <typename Graph>
   630   UndirGraphWriter<Graph> undirGraphWriter(const std::string& fn, 
   631 					   const Graph &g) {
   632     return UndirGraphWriter<Graph>(fn, g);
   633   }
   634 
   635   /// @}
   636 
   637 }
   638 
   639 #endif