lemon/graph_writer.h
author alpar
Fri, 03 Feb 2006 09:03:05 +0000
changeset 1948 9e9c035a08be
parent 1909 2d806130e700
child 1956 a055123339d5
permissions -rw-r--r--
Hopefully we can release 0.5 today
     1 /* -*- C++ -*-
     2  * lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2006 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 "label" should write a unique map because it 
    58   /// is regarded as label map (such a map is essential if the graph has edges).
    59   ///
    60   ///\code
    61   /// IdMap<ListGraph, Node> nodeLabelMap;
    62   /// writer.writeNodeMap("label", nodeLabelMap);
    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 label of the given node.
   257     ///
   258     /// It writes the label of the given node. If there was written an "label"
   259     /// named node map then it will write the map value belonging to the node.
   260     void writeLabel(std::ostream& os, const Node& item) const {
   261       nodeset_writer.writeLabel(os, item);
   262     } 
   263 
   264     /// \brief Write the label of the given edge.
   265     ///
   266     /// It writes the label of the given edge. If there was written an "label"
   267     /// named edge map then it will write the map value belonging to the edge.
   268     void writeLabel(std::ostream& os, const Edge& item) const {
   269       edgeset_writer.writeLabel(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 UGraphWriter class provides the ugraph 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 UEdgeMap 
   321   /// writing and labeled Node, Edge or UEdge writing.
   322   ///
   323   ///\code
   324   /// UGraphWriter<ListUGraph> writer(std::cout, graph);
   325   ///\endcode
   326   ///
   327   /// The \c writeNodeMap() function declares a \c NodeMap writing 
   328   /// command in the \c UGraphWriter. You should give as parameter 
   329   /// the name of the map and the map object. The NodeMap writing 
   330   /// command with name "label" should write a unique map because it 
   331   /// is regarded as label map.
   332   ///
   333   ///\code
   334   /// IdMap<ListUGraph, Node> nodeLabelMap;
   335   /// writer.writeNodeMap("label", nodeLabelMap);
   336   ///
   337   /// writer.writeNodeMap("coords", coords);
   338   /// writer.writeNodeMap("color", colorMap);
   339   ///\endcode
   340   ///
   341   /// With the \c writeUEdgeMap() 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.writeUEdgeMap("descriptor", edgeDescMap);
   348   ///
   349   /// writer.writeUEdgeMap("weight", weightMap);
   350   /// writer.writeUEdgeMap("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 writeUEdge() 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.writeUEdge("observed", uEdge);
   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 UGraphWriter {
   388   public:
   389     
   390     typedef _Graph Graph;
   391     typedef typename Graph::Node Node;
   392     typedef typename Graph::Edge Edge;
   393     typedef typename Graph::UEdge UEdge;
   394 
   395     typedef _WriterTraits WriterTraits;
   396 
   397     /// \brief Construct a new UGraphWriter.
   398     ///
   399     /// Construct a new UGraphWriter. It writes the given graph
   400     /// to the given stream.
   401     UGraphWriter(std::ostream& _os, const Graph& _graph) 
   402       : writer(new LemonWriter(_os)), own_writer(true), 
   403 	nodeset_writer(*writer, _graph, std::string()),
   404 	u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   405 	node_writer(*writer, nodeset_writer, std::string()),
   406 	u_edge_writer(*writer, u_edgeset_writer, std::string()),
   407 	attribute_writer(*writer, std::string()) {}
   408 
   409     /// \brief Construct a new UGraphWriter.
   410     ///
   411     /// Construct a new UGraphWriter. It writes the given graph
   412     /// to the given file.
   413     UGraphWriter(const std::string& _filename, const Graph& _graph) 
   414       : writer(new LemonWriter(_filename)), own_writer(true), 
   415 	nodeset_writer(*writer, _graph, std::string()),
   416 	u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   417 	node_writer(*writer, nodeset_writer, std::string()),
   418 	u_edge_writer(*writer, u_edgeset_writer, std::string()),
   419 	attribute_writer(*writer, std::string()) {}
   420 
   421     /// \brief Construct a new UGraphWriter.
   422     ///
   423     /// Construct a new UGraphWriter. It writes the given graph
   424     /// to given LemonReader.
   425     UGraphWriter(LemonWriter& _writer, const Graph& _graph)
   426       : writer(_writer), own_writer(false), 
   427 	nodeset_writer(*writer, _graph, std::string()),
   428 	u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   429 	node_writer(*writer, nodeset_writer, std::string()),
   430 	u_edge_writer(*writer, u_edgeset_writer, std::string()),
   431 	attribute_writer(*writer, std::string()) {}
   432 
   433     /// \brief Destruct the graph writer.
   434     ///
   435     /// Destruct the graph writer.
   436     ~UGraphWriter() {
   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     UGraphWriter& 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     UGraphWriter& 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     UGraphWriter& writeEdgeMap(std::string name, const Map& map) { 
   465       u_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     UGraphWriter& writeEdgeMap(std::string name, const Map& map,
   474 				   const Writer& writer = Writer()) {
   475       u_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     UGraphWriter& writeUEdgeMap(std::string name, const Map& map) { 
   485       u_edgeset_writer.writeUEdgeMap(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     UGraphWriter& writeUEdgeMap(std::string name, const Map& map,
   495 					const Writer& writer = Writer()) {
   496       u_edgeset_writer.writeUEdgeMap(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     UGraphWriter& 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     UGraphWriter& writeEdge(std::string name, const Edge& edge) {
   514       u_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     UGraphWriter& writeUEdge(std::string name, const UEdge& edge) {
   523       u_edge_writer.writeUEdge(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     UGraphWriter& 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     UGraphWriter& 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 label of the given node.
   565     ///
   566     /// It writes the label of the given node. If there was written an "label"
   567     /// named node map then it will write the map value belonging to the node.
   568     void writeLabel(std::ostream& os, const Node& item) const {
   569       nodeset_writer.writeLabel(os, item);
   570     } 
   571 
   572     /// \brief Write the label of the given edge.
   573     ///
   574     /// It writes the label of the given edge. If there was written an "label"
   575     /// named edge map then it will write the map value belonging to the edge.
   576     void writeLabel(std::ostream& os, const Edge& item) const {
   577       u_edgeset_writer.writeLabel(os, item);
   578     } 
   579 
   580     /// \brief Write the label of the given undirected edge.
   581     ///
   582     /// It writes the label of the given undirected edge. If there was written 
   583     /// an "label" named edge map then it will write the map value belonging to 
   584     /// the edge.
   585     void writeLabel(std::ostream& os, const UEdge& item) const {
   586       u_edgeset_writer.writeLabel(os, item);
   587     } 
   588 
   589 
   590   private:
   591 
   592     LemonWriter* writer;
   593     bool own_writer;
   594 
   595     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   596     UEdgeSetWriter<Graph, WriterTraits> u_edgeset_writer;
   597 
   598     NodeWriter<Graph> node_writer;
   599     UEdgeWriter<Graph> u_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 UGraphWriter 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   UGraphWriter<Graph> uGraphWriter(std::ostream& os, const Graph &g) {
   615     return UGraphWriter<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 UGraphWriter 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   UGraphWriter<Graph> uGraphWriter(const std::string& fn, 
   631 					   const Graph &g) {
   632     return UGraphWriter<Graph>(fn, g);
   633   }
   634 
   635   /// @}
   636 
   637 }
   638 
   639 #endif