lemon/graph_writer.h
author deba
Wed, 01 Mar 2006 10:17:25 +0000
changeset 1990 15fb7a4ea6be
parent 1946 17eb3eaad9f8
child 2037 32e4bebee616
permissions -rw-r--r--
Some classes assumed that the GraphMaps should be inherited
from an ObserverBase. These classes parents replaced with
DefaultMap which cause that the graph maps should not be
inherited from the ObserverBase.
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2006
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     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.
    12  *
    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
    15  * purpose.
    16  *
    17  */
    18 
    19 ///\ingroup io_group
    20 ///\file
    21 ///\brief Lemon Graph Format writer.
    22 ///
    23 
    24 #ifndef LEMON_GRAPH_WRITER_H
    25 #define LEMON_GRAPH_WRITER_H
    26 
    27 #include <iostream>
    28 
    29 #include <lemon/error.h>
    30 #include <lemon/lemon_writer.h>
    31 
    32 namespace lemon {
    33 
    34   /// \addtogroup io_group
    35   /// @{
    36 
    37   /// \brief The graph writer class.
    38   ///
    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".
    42   ///
    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).
    46   ///
    47   /// To write a graph
    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
    50   /// Edge writing.
    51   ///
    52   ///\code
    53   /// GraphWriter<ListGraph> writer(std::cout, graph);
    54   ///\endcode
    55   ///
    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).
    61   ///
    62   ///\code
    63   /// IdMap<ListGraph, Node> nodeLabelMap;
    64   /// writer.writeNodeMap("label", nodeLabelMap);
    65   ///
    66   /// writer.writeNodeMap("coords", coords);
    67   /// writer.writeNodeMap("color", colorMap);
    68   ///\endcode
    69   ///
    70   /// With the \c writeEdgeMap() member function you can give an edge map
    71   /// writing command similar to the NodeMaps.
    72   ///
    73   ///\code
    74   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
    75   ///   edgeDescMap(graph);
    76   /// writer.writeEdgeMap("descriptor", edgeDescMap);
    77   ///
    78   /// writer.writeEdgeMap("weight", weightMap);
    79   /// writer.writeEdgeMap("label", labelMap);
    80   ///\endcode
    81   ///
    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.
    85   ///
    86   ///\code
    87   /// writer.writeNode("source", sourceNode);
    88   /// writer.writeNode("target", targetNode);
    89   ///
    90   /// writer.writeEdge("observed", edge);
    91   ///\endcode
    92   ///
    93   /// After you give all write commands you must call the \c run() member
    94   /// function, which executes all the writing commands.
    95   ///
    96   ///\code
    97   /// writer.run();
    98   ///\endcode
    99   ///
   100   /// \see DefaultWriterTraits
   101   /// \see QuotedStringWriter
   102   /// \see IdMap
   103   /// \see DescriptorMap
   104   /// \see \ref GraphReader
   105   /// \see \ref graph-io-page
   106   /// \author Balazs Dezso
   107   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   108   class GraphWriter {
   109   public:
   110     
   111     typedef _Graph Graph;
   112     typedef typename Graph::Node Node;
   113     typedef typename Graph::Edge Edge;
   114 
   115     typedef _WriterTraits WriterTraits;
   116 
   117     /// \brief Construct a new GraphWriter.
   118     ///
   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()) {}
   128 
   129     /// \brief Construct a new GraphWriter.
   130     ///
   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()) {}
   140 
   141     /// \brief Construct a new GraphWriter.
   142     ///
   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()) {}
   152 
   153     /// \brief Destruct the graph writer.
   154     ///
   155     /// This function destructs the graph writer.
   156     ~GraphWriter() {
   157       if (own_writer) 
   158 	delete writer;
   159     }
   160 
   161     /// \brief Issue a new node map writing command for the writer.
   162     ///
   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);
   167       return *this;
   168     }
   169 
   170 
   171     /// \brief Issue a new node map writing command for the writer.
   172     ///
   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);
   178       return *this;
   179     }
   180 
   181 
   182     /// \brief Issue a new edge map writing command for the writer.
   183     ///
   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);
   188       return *this;
   189     }
   190 
   191 
   192     /// \brief Issue a new edge map writing command for the writer.
   193     ///
   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);
   199       return *this;
   200     }
   201 
   202     /// \brief Issue a new labeled node writing command to the writer.
   203     ///
   204     /// This function issues a new <i> labeled node writing command</i> 
   205     /// to the writer.
   206     GraphWriter& writeNode(std::string name, const Node& node) {
   207       node_writer.writeNode(name, node);
   208       return *this;
   209     }
   210 
   211     /// \brief Issue a new labeled edge writing command to the writer.
   212     ///
   213     /// This function issues a new <i> labeled edge writing command</i> 
   214     /// to the writer.
   215     GraphWriter& writeEdge(std::string name, const Edge& edge) {
   216       edge_writer.writeEdge(name, edge);
   217     }
   218 
   219     /// \brief Issue a new attribute writing command.
   220     ///
   221     /// This function issues a new <i> attribute writing command</i> 
   222     /// to the writer.
   223     template <typename Value>
   224     GraphWriter& writeAttribute(std::string name, const Value& value) {
   225       attribute_writer.writeAttribute(name, value);
   226       return *this;
   227     }
   228     
   229     /// \brief Issue a new attribute writing command.
   230     ///
   231     /// This function issues a new <i> attribute writing command</i> 
   232     /// to the writer.
   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);
   237       return *this;
   238     }
   239 
   240     /// \brief Conversion operator to LemonWriter.
   241     ///
   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&() {
   248       return *writer;
   249     }
   250 
   251     /// \brief Executes the writing commands.
   252     ///
   253     /// Executes the writing commands.
   254     void run() {
   255       writer->run();
   256     }
   257 
   258     /// \brief Write the label of the given node.
   259     ///
   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);
   264     } 
   265 
   266     /// \brief Write the label of the given edge.
   267     ///
   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);
   272     } 
   273 
   274   private:
   275 
   276     LemonWriter* writer;
   277     bool own_writer;
   278 
   279     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   280     EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
   281 
   282     NodeWriter<Graph> node_writer;
   283     EdgeWriter<Graph> edge_writer;
   284     
   285     AttributeWriter<WriterTraits> attribute_writer;
   286   };
   287 
   288 
   289 
   290   /// \brief Write a graph to the output.
   291   ///
   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.
   296   ///
   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);
   302   }
   303 
   304   /// \brief Write a graph to the output.
   305   ///
   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.
   310   ///
   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);
   316   }
   317 
   318   /// \brief The undirected graph writer class.
   319   ///
   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.
   324   ///
   325   ///\code
   326   /// UGraphWriter<ListUGraph> writer(std::cout, graph);
   327   ///\endcode
   328   ///
   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.
   334   ///
   335   ///\code
   336   /// IdMap<ListUGraph, Node> nodeLabelMap;
   337   /// writer.writeNodeMap("label", nodeLabelMap);
   338   ///
   339   /// writer.writeNodeMap("coords", coords);
   340   /// writer.writeNodeMap("color", colorMap);
   341   ///\endcode
   342   ///
   343   /// With the \c writeUEdgeMap() member function you can give an 
   344   /// undirected edge map writing command similar to the NodeMaps.
   345   ///
   346   ///\code
   347   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
   348   ///   edgeDescMap(graph);
   349   /// writer.writeUEdgeMap("descriptor", edgeDescMap);
   350   ///
   351   /// writer.writeUEdgeMap("weight", weightMap);
   352   /// writer.writeUEdgeMap("label", labelMap);
   353   ///\endcode
   354   /// 
   355   /// The EdgeMap handling is just a syntactical sugar. It writes
   356   /// two undirected edge map with '+' and '-' prefix in the name.
   357   ///
   358   ///\code
   359   /// writer.writeEdgeMap("capacity", capacityMap);
   360   ///\endcode
   361   ///
   362   ///
   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.
   366   ///
   367   ///\code
   368   /// writer.writeNode("source", sourceNode);
   369   /// writer.writeNode("target", targetNode);
   370   ///
   371   /// writer.writeUEdge("observed", uEdge);
   372   ///\endcode
   373   ///
   374   /// After you give all write commands you must call the \c run() member
   375   /// function, which executes all the writing commands.
   376   ///
   377   ///\code
   378   /// writer.run();
   379   ///\endcode
   380   ///
   381   /// \see DefaultWriterTraits
   382   /// \see QuotedStringWriter
   383   /// \see IdMap
   384   /// \see DescriptorMap
   385   /// \see \ref GraphWriter
   386   /// \see \ref graph-io-page
   387   /// \author Balazs Dezso
   388   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   389   class UGraphWriter {
   390   public:
   391     
   392     typedef _Graph Graph;
   393     typedef typename Graph::Node Node;
   394     typedef typename Graph::Edge Edge;
   395     typedef typename Graph::UEdge UEdge;
   396 
   397     typedef _WriterTraits WriterTraits;
   398 
   399     /// \brief Construct a new UGraphWriter.
   400     ///
   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()) {}
   410 
   411     /// \brief Construct a new UGraphWriter.
   412     ///
   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()) {}
   422 
   423     /// \brief Construct a new UGraphWriter.
   424     ///
   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()) {}
   434 
   435     /// \brief Destruct the graph writer.
   436     ///
   437     /// Destruct the graph writer.
   438     ~UGraphWriter() {
   439       if (own_writer) 
   440 	delete writer;
   441     }
   442 
   443     /// \brief Issue a new node map writing command to the writer.
   444     ///
   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);
   449       return *this;
   450     }
   451 
   452     /// \brief Issue a new node map writing command to the writer.
   453     ///
   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);
   459       return *this;
   460     }
   461 
   462     /// \brief Issue a new edge map writing command to the writer.
   463     ///
   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);
   468       return *this;
   469     }
   470 
   471     /// \brief Issue a new edge map writing command to the writer.
   472     ///
   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);
   478       return *this;
   479     }
   480 
   481     /// \brief Issue a new undirected edge map writing command to the writer.
   482     ///
   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);
   488       return *this;
   489     }
   490 
   491     /// \brief Issue a new undirected edge map writing command to the writer.
   492     ///
   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);
   499       return *this;
   500     }
   501 
   502     /// \brief Issue a new labeled node writer to the writer.
   503     ///
   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);
   508       return *this;
   509     }
   510 
   511     /// \brief Issue a new labeled edge writer to the writer.
   512     ///
   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);
   517     }
   518 
   519     /// \brief Issue a new labeled undirected edge writing command to
   520     /// the writer.
   521     ///
   522     /// Issue a new <i>labeled undirected edge writing command</i> to
   523     /// the writer.
   524     UGraphWriter& writeUEdge(std::string name, const UEdge& edge) {
   525       u_edge_writer.writeUEdge(name, edge);
   526     }
   527 
   528     /// \brief Issue a new attribute writing command.
   529     ///
   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);
   535       return *this;
   536     }
   537     
   538     /// \brief Issue a new attribute writing command.
   539     ///
   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);
   546       return *this;
   547     }
   548 
   549     /// \brief Conversion operator to LemonWriter.
   550     ///
   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&() {
   556       return *writer;
   557     }
   558 
   559     /// \brief Executes the writing commands.
   560     ///
   561     /// Executes the writing commands.
   562     void run() {
   563       writer->run();
   564     }
   565 
   566     /// \brief Write the label of the given node.
   567     ///
   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);
   572     } 
   573 
   574     /// \brief Write the label of the given edge.
   575     ///
   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);
   580     } 
   581 
   582     /// \brief Write the label of the given undirected edge.
   583     ///
   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 
   586     /// the edge.
   587     void writeLabel(std::ostream& os, const UEdge& item) const {
   588       u_edgeset_writer.writeLabel(os, item);
   589     } 
   590 
   591 
   592   private:
   593 
   594     LemonWriter* writer;
   595     bool own_writer;
   596 
   597     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   598     UEdgeSetWriter<Graph, WriterTraits> u_edgeset_writer;
   599 
   600     NodeWriter<Graph> node_writer;
   601     UEdgeWriter<Graph> u_edge_writer;
   602     
   603     AttributeWriter<WriterTraits> attribute_writer;
   604   };
   605 
   606   /// \brief Write an undirected graph to the output.
   607   ///
   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.
   612   ///
   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);
   618   }
   619 
   620   /// \brief Write an undirected graph to the output.
   621   ///
   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 
   625   /// attributes.
   626   ///
   627   /// \warning Do not forget to call the \c run() function.
   628   ///
   629   /// \param fn The output file.
   630   /// \param g The graph.
   631   template <typename Graph>
   632   UGraphWriter<Graph> uGraphWriter(const std::string& fn, 
   633 					   const Graph &g) {
   634     return UGraphWriter<Graph>(fn, g);
   635   }
   636 
   637   /// @}
   638 
   639 }
   640 
   641 #endif