lemon/graph_writer.h
author athos
Mon, 04 Jul 2005 16:11:33 +0000
changeset 1534 b86aad11f842
parent 1526 8c14aa8f27a2
child 1540 7d028a73d7f2
permissions -rw-r--r--
Doc.
     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   /// If you don't need very sophisticated
    41   /// behaviour then you can use the versions of the public function
    42   /// \ref writeGraph() to output a graph (or a max flow instance etc).
    43   ///
    44   /// To write a graph
    45   /// you should first give writing commands to the writer. You can declare
    46   /// write commands as \c NodeMap or \c EdgeMap writing and labeled Node and
    47   /// Edge writing.
    48   ///
    49   /// \code
    50   /// GraphWriter<ListGraph> writer(std::cout, graph);
    51   /// \endcode
    52   ///
    53   /// The \c writeNodeMap() function declares a \c NodeMap writing 
    54   /// command in the \c GraphWriter. You should give as parameter 
    55   /// the name of the map and the map object. The NodeMap writing 
    56   /// command with name "id" should write a unique map because it 
    57   /// is regarded as ID map (such a map is essential if the graph has edges).
    58   ///
    59   /// \code
    60   /// IdMap<ListGraph, Node> nodeIdMap;
    61   /// writer.writeNodeMap("id", nodeIdMap);
    62   ///
    63   /// writer.writeNodeMap("coords", coords);
    64   /// writer.writeNodeMap("color", colorMap);
    65   /// \endcode
    66   ///
    67   /// With the \c writeEdgeMap() member function you can give an edge map
    68   /// writing command similar to the NodeMaps.
    69   ///
    70   /// \code
    71   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
    72   ///   edgeDescMap(graph);
    73   /// writer.writeEdgeMap("descriptor", edgeDescMap);
    74   ///
    75   /// writer.writeEdgeMap("weight", weightMap);
    76   /// writer.writeEdgeMap("label", labelMap);
    77   /// \endcode
    78   ///
    79   /// With \c writeNode() and \c writeEdge() functions you can 
    80   /// point out Nodes and Edges in the graph. For example, you can 
    81   /// write out the source and target of a maximum flow instance.
    82   ///
    83   /// \code
    84   /// writer.writeNode("source", sourceNode);
    85   /// writer.writeNode("target", targetNode);
    86   ///
    87   /// writer.writeEdge("observed", edge);
    88   /// \endcode
    89   ///
    90   /// After you give all write commands you must call the \c run() member
    91   /// function, which executes all the writing commands.
    92   ///
    93   /// \code
    94   /// writer.run();
    95   /// \endcode
    96   ///
    97   /// \see DefaultWriterTraits
    98   /// \see QuotedStringWriter
    99   /// \see IdMap
   100   /// \see DescriptorMap
   101   /// \see \ref GraphReader
   102   /// \see \ref graph-io-page
   103   /// \author Balazs Dezso
   104   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   105   class GraphWriter {
   106   public:
   107     
   108     typedef _Graph Graph;
   109     typedef typename Graph::Node Node;
   110     typedef typename Graph::Edge Edge;
   111 
   112     typedef _WriterTraits WriterTraits;
   113 
   114     /// \brief Construct a new GraphWriter.
   115     ///
   116     /// This function constructs a new GraphWriter to write the given graph
   117     /// to the given stream.
   118     GraphWriter(std::ostream& _os, const Graph& _graph) 
   119       : writer(new LemonWriter(_os)), own_writer(true), 
   120 	nodeset_writer(*writer, _graph, std::string()),
   121 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   122 	node_writer(*writer, nodeset_writer, std::string()),
   123 	edge_writer(*writer, edgeset_writer, std::string()),
   124 	attribute_writer(*writer, std::string()) {}
   125 
   126     /// \brief Construct a new GraphWriter.
   127     ///
   128     /// This function constructs a new GraphWriter to write the given graph
   129     /// to the given file.
   130     GraphWriter(const std::string& _filename, const Graph& _graph) 
   131       : writer(new LemonWriter(_filename)), own_writer(true), 
   132 	nodeset_writer(*writer, _graph, std::string()),
   133 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   134 	node_writer(*writer, nodeset_writer, std::string()),
   135 	edge_writer(*writer, edgeset_writer, std::string()),
   136 	attribute_writer(*writer, std::string()) {}
   137 
   138     /// \brief Construct a new GraphWriter.
   139     ///
   140     /// This function constructs a new GraphWriter to write the given graph
   141     /// to the given LemonReader.
   142     GraphWriter(LemonWriter& _writer, const Graph& _graph)
   143       : writer(_writer), own_writer(false), 
   144 	nodeset_writer(*writer, _graph, std::string()),
   145 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   146 	node_writer(*writer, nodeset_writer, std::string()),
   147 	edge_writer(*writer, edgeset_writer, std::string()),
   148 	attribute_writer(*writer, std::string()) {}
   149 
   150     /// \brief Destruct the graph writer.
   151     ///
   152     /// This function destructs the graph writer.
   153     ~GraphWriter() {
   154       if (own_writer) 
   155 	delete writer;
   156     }
   157 
   158     /// \brief Issue a new node map writing command for the writer.
   159     ///
   160    /// This function issues a new <i> node map writing command</i> to the writer.
   161     template <typename Map>
   162     GraphWriter& writeNodeMap(std::string name, const Map& map) {
   163       nodeset_writer.writeNodeMap(name, map);
   164       return *this;
   165     }
   166 
   167     /// \brief Issue a new node map writing command for the writer.
   168     ///
   169    /// This function issues a new <i> node map writing command</i> to the writer.
   170     template <typename Writer, typename Map>
   171     GraphWriter& writeNodeMap(std::string name, const Map& map, 
   172 			      const Writer& writer = Writer()) {
   173       nodeset_writer.writeNodeMap(name, map, writer);
   174       return *this;
   175     }
   176 
   177 
   178     /// \brief Issue a new edge map writing command for the writer.
   179     ///
   180    /// This function issues a new <i> edge map writing command</i> to the writer.
   181     template <typename Map>
   182     GraphWriter& writeEdgeMap(std::string name, const Map& map) { 
   183       edgeset_writer.writeEdgeMap(name, map);
   184       return *this;
   185     }
   186 
   187 
   188     /// \brief Issue a new edge map writing command for the writer.
   189     ///
   190    /// This function issues a new <i> edge map writing command</i> to the writer.
   191     template <typename Writer, typename Map>
   192     GraphWriter& writeEdgeMap(std::string name, const Map& map,
   193 			      const Writer& writer = Writer()) {
   194       edgeset_writer.writeEdgeMap(name, map, writer);
   195       return *this;
   196     }
   197 
   198     /// \brief Issue a new labeled node writing command to the writer.
   199     ///
   200     /// This function issues a new <i> labeled node writing command</i> 
   201     /// to the writer.
   202     GraphWriter& writeNode(std::string name, const Node& node) {
   203       node_writer.writeNode(name, node);
   204       return *this;
   205     }
   206 
   207     /// \brief Issue a new labeled edge writing command to the writer.
   208     ///
   209     /// This function issues a new <i> labeled edge writing command</i> 
   210     /// to the writer.
   211     GraphWriter& writeEdge(std::string name, const Edge& edge) {
   212       edge_writer.writeEdge(name, edge);
   213     }
   214 
   215     /// \brief Issue a new attribute writing command.
   216     ///
   217     /// This function issues a new <i> attribute writing command</i> 
   218     /// to the writer.
   219     template <typename Value>
   220     GraphWriter& writeAttribute(std::string name, const Value& value) {
   221       attribute_writer.writeAttribute(name, value);
   222       return *this;
   223     }
   224     
   225     /// \brief Issue a new attribute writing command.
   226     ///
   227     /// This function issues a new <i> attribute writing command</i> 
   228     /// to the writer.
   229     template <typename Writer, typename Value>
   230     GraphWriter& writeAttribute(std::string name, const Value& value, 
   231 			       const Writer& writer) {
   232       attribute_writer.writeAttribute<Writer>(name, value, writer);
   233       return *this;
   234     }
   235 
   236     /// \brief Conversion operator to LemonWriter.
   237     ///
   238     /// Conversion operator to LemonWriter. It makes possible
   239     /// to access the encapsulated \e LemonWriter, this way
   240     /// you can attach to this writer new instances of 
   241     /// \e LemonWriter::SectionWriter.
   242     operator LemonWriter&() {
   243       return *writer;
   244     }
   245 
   246     /// \brief Executes the writing commands.
   247     ///
   248     /// Executes the writing commands.
   249     void run() {
   250       writer->run();
   251     }
   252 
   253     /// \brief Write the id of the given node.
   254     ///
   255     /// It writes the id of the given node. If there was written an "id"
   256     /// named node map then it will write the map value belonging to the node.
   257     void writeId(std::ostream& os, const Node& item) const {
   258       nodeset_writer.writeId(os, item);
   259     } 
   260 
   261     /// \brief Write the id of the given edge.
   262     ///
   263     /// It writes the id of the given edge. If there was written an "id"
   264     /// named edge map then it will write the map value belonging to the edge.
   265     void writeId(std::ostream& os, const Edge& item) const {
   266       edgeset_writer.writeId(os, item);
   267     } 
   268 
   269   private:
   270 
   271     LemonWriter* writer;
   272     bool own_writer;
   273 
   274     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   275     EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
   276 
   277     NodeWriter<Graph> node_writer;
   278     EdgeWriter<Graph> edge_writer;
   279     
   280     AttributeWriter<WriterTraits> attribute_writer;
   281   };
   282 
   283 
   284   ///\anchor writeGraph()
   285   ///
   286   /// \brief Write a graph to the output.
   287   ///
   288   /// Write a graph to the output.
   289   /// \param os The output stream.
   290   /// \param g The graph.
   291   template<typename Graph>
   292   void writeGraph(std::ostream& os, const Graph &g) {
   293     GraphWriter<Graph> writer(os, g);
   294     IdMap<Graph, typename Graph::Node> nodeIdMap(g);
   295     writer.writeNodeMap("id", nodeIdMap);
   296     IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
   297     writer.writeEdgeMap("id", edgeIdMap);
   298     writer.run();
   299   }
   300 
   301   /// \brief Write a capacitated graph instance to the output.
   302   /// 
   303   /// Write a capacitated graph (graph+capacity on the
   304   /// edges) to the output.
   305   /// \param os The output stream.
   306   /// \param g The graph.
   307   /// \param capacity The capacity map.
   308   template<typename Graph, typename CapacityMap>
   309   void writeGraph(std::ostream& os, const Graph &g, 
   310 		  const CapacityMap& capacity) {
   311     GraphWriter<Graph> writer(os, g);
   312     IdMap<Graph, typename Graph::Node> nodeIdMap(g);
   313     writer.writeNodeMap("id", nodeIdMap);
   314     IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
   315     writer.writeEdgeMap("id", edgeIdMap);
   316     writer.writeEdgeMap("capacity", capacity);
   317     writer.run();
   318   }
   319 
   320   /// \brief Write a shortest path instance to the output.
   321   /// 
   322   /// Write a shortest path instance (graph+capacity on the
   323   /// edges+designated source) to the output.
   324   /// \param os The output stream.
   325   /// \param g The graph.
   326   /// \param capacity The capacity map.
   327   /// \param s The source node.
   328   template<typename Graph, typename CapacityMap>
   329   void writeGraph(std::ostream& os, const Graph &g, 
   330 		  const CapacityMap& capacity, const typename Graph::Node &s) {
   331     GraphWriter<Graph> writer(os, g);
   332     IdMap<Graph, typename Graph::Node> nodeIdMap(g);
   333     writer.writeNodeMap("id", nodeIdMap);
   334     IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
   335     writer.writeEdgeMap("id", edgeIdMap);
   336     writer.writeEdgeMap("capacity", capacity);
   337     writer.writeNode("source", s);
   338     writer.run();
   339   }
   340 
   341 
   342   /// \brief Write a max flow instance to the output.
   343   ///
   344   /// Write a max flow instance (graph+capacity on the
   345   /// edges+designated source and target) to the output.
   346   ///
   347   /// \param os The output stream.
   348   /// \param g The graph.
   349   /// \param capacity The capacity map.
   350   /// \param s The source node.
   351   /// \param t The target node.
   352   template<typename Graph, typename CapacityMap>
   353   void writeGraph(std::ostream& os, const Graph &g, 
   354 		  const CapacityMap& capacity, const typename Graph::Node &s,
   355 		  const typename Graph::Node &t) {
   356     GraphWriter<Graph> writer(os, g);
   357     IdMap<Graph, typename Graph::Node> nodeIdMap(g);
   358     writer.writeNodeMap("id", nodeIdMap);
   359     IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
   360     writer.writeEdgeMap("id", edgeIdMap);
   361     writer.writeEdgeMap("capacity", capacity);
   362     writer.writeNode("source", s);
   363     writer.writeNode("target", t);
   364     writer.run();
   365   }
   366 
   367   /// \brief Write a min cost flow instance to the output.
   368   ///
   369   /// Write a min cost flow instance (graph+capacity on the edges+cost
   370   /// function on the edges+designated source and target) to the output.
   371   ///
   372   /// \param os The output stream.
   373   /// \param g The graph.
   374   /// \param capacity The capacity map.
   375   /// \param s The source node.
   376   /// \param t The target node.
   377   /// \param cost The cost map.
   378   template<typename Graph, typename CapacityMap, typename CostMap>
   379   void writeGraph(std::ostream& os, const Graph &g, 
   380 		  const CapacityMap& capacity, const typename Graph::Node &s,
   381 		  const typename Graph::Node &t, const CostMap& cost) {
   382     GraphWriter<Graph> writer(os, g);
   383     IdMap<Graph, typename Graph::Node> nodeIdMap(g);
   384     writer.writeNodeMap("id", nodeIdMap);
   385     IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
   386     writer.writeEdgeMap("id", edgeIdMap);
   387     writer.writeEdgeMap("capacity", capacity);
   388     writer.writeEdgeMap("cost", cost);
   389     writer.writeNode("source", s);
   390     writer.writeNode("target", t);
   391     writer.run();
   392   }
   393 
   394   /// \brief The undirected graph writer class.
   395   ///
   396   /// The \c UndirGraphWriter class provides the undir graph output. To write 
   397   /// a graph you should first give writing commands to the writer. You can 
   398   /// declare write command as \c NodeMap, \c EdgeMap or \c UndirEdgeMap 
   399   /// writing and labeled Node, Edge or UndirEdge writing.
   400   ///
   401   /// \code
   402   /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph);
   403   /// \endcode
   404   ///
   405   /// The \c writeNodeMap() function declares a \c NodeMap writing 
   406   /// command in the \c UndirGraphWriter. You should give as parameter 
   407   /// the name of the map and the map object. The NodeMap writing 
   408   /// command with name "id" should write a unique map because it 
   409   /// is regarded as ID map.
   410   ///
   411   /// \code
   412   /// IdMap<UndirListGraph, Node> nodeIdMap;
   413   /// writer.writeNodeMap("id", nodeIdMap);
   414   ///
   415   /// writer.writeNodeMap("coords", coords);
   416   /// writer.writeNodeMap("color", colorMap);
   417   /// \endcode
   418   ///
   419   /// With the \c writeUndirEdgeMap() member function you can give an 
   420   /// undirected edge map writing command similar to the NodeMaps.
   421   ///
   422   /// \code
   423   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
   424   ///   edgeDescMap(graph);
   425   /// writer.writeUndirEdgeMap("descriptor", edgeDescMap);
   426   ///
   427   /// writer.writeUndirEdgeMap("weight", weightMap);
   428   /// writer.writeUndirEdgeMap("label", labelMap);
   429   /// \endcode
   430   /// 
   431   /// The EdgeMap handling is just a syntactical sugar. It writes
   432   /// two undirected edge map with '+' and '-' prefix in the name.
   433   ///
   434   /// \code
   435   /// writer.writeEdgeMap("capacity", capacityMap);
   436   /// \endcode
   437   ///
   438   ///
   439   /// With \c writeNode() and \c writeUndirEdge() functions you can 
   440   /// designate nodes and undirected edges in the graph. For example, you can 
   441   /// write out the source and target of the graph.
   442   ///
   443   /// \code
   444   /// writer.writeNode("source", sourceNode);
   445   /// writer.writeNode("target", targetNode);
   446   ///
   447   /// writer.writeUndirEdge("observed", undirEdge);
   448   /// \endcode
   449   ///
   450   /// After you give all write commands you must call the \c run() member
   451   /// function, which executes all the writing commands.
   452   ///
   453   /// \code
   454   /// writer.run();
   455   /// \endcode
   456   ///
   457   /// \see DefaultWriterTraits
   458   /// \see QuotedStringWriter
   459   /// \see IdMap
   460   /// \see DescriptorMap
   461   /// \see \ref GraphWriter
   462   /// \see \ref graph-io-page
   463   /// \author Balazs Dezso
   464   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   465   class UndirGraphWriter {
   466   public:
   467     
   468     typedef _Graph Graph;
   469     typedef typename Graph::Node Node;
   470     typedef typename Graph::Edge Edge;
   471     typedef typename Graph::UndirEdge UndirEdge;
   472 
   473     typedef _WriterTraits WriterTraits;
   474 
   475     /// \brief Construct a new UndirGraphWriter.
   476     ///
   477     /// Construct a new UndirGraphWriter. It writes the given graph
   478     /// to the given stream.
   479     UndirGraphWriter(std::ostream& _os, const Graph& _graph) 
   480       : writer(new LemonWriter(_os)), own_writer(true), 
   481 	nodeset_writer(*writer, _graph, std::string()),
   482 	undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   483 	node_writer(*writer, nodeset_writer, std::string()),
   484 	undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
   485 	attribute_writer(*writer, std::string()) {}
   486 
   487     /// \brief Construct a new UndirGraphWriter.
   488     ///
   489     /// Construct a new UndirGraphWriter. It writes the given graph
   490     /// to the given file.
   491     UndirGraphWriter(const std::string& _filename, const Graph& _graph) 
   492       : writer(new LemonWriter(_filename)), own_writer(true), 
   493 	nodeset_writer(*writer, _graph, std::string()),
   494 	undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   495 	node_writer(*writer, nodeset_writer, std::string()),
   496 	undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
   497 	attribute_writer(*writer, std::string()) {}
   498 
   499     /// \brief Construct a new UndirGraphWriter.
   500     ///
   501     /// Construct a new UndirGraphWriter. It writes the given graph
   502     /// to given LemonReader.
   503     UndirGraphWriter(LemonWriter& _writer, const Graph& _graph)
   504       : writer(_writer), own_writer(false), 
   505 	nodeset_writer(*writer, _graph, std::string()),
   506 	undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   507 	node_writer(*writer, nodeset_writer, std::string()),
   508 	undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
   509 	attribute_writer(*writer, std::string()) {}
   510 
   511     /// \brief Destruct the graph writer.
   512     ///
   513     /// Destruct the graph writer.
   514     ~UndirGraphWriter() {
   515       if (own_writer) 
   516 	delete writer;
   517     }
   518 
   519     /// \brief Issue a new node map writing command to the writer.
   520     ///
   521    /// This function issues a new <i> node map writing command</i> to the writer.
   522     template <typename Map>
   523     UndirGraphWriter& writeNodeMap(std::string name, const Map& map) {
   524       nodeset_writer.writeNodeMap(name, map);
   525       return *this;
   526     }
   527 
   528     /// \brief Issue a new node map writing command to the writer.
   529     ///
   530    /// This function issues a new <i> node map writing command</i> to the writer.
   531     template <typename Writer, typename Map>
   532     UndirGraphWriter& writeNodeMap(std::string name, const Map& map, 
   533 			      const Writer& writer = Writer()) {
   534       nodeset_writer.writeNodeMap(name, map, writer);
   535       return *this;
   536     }
   537 
   538     /// \brief Issue a new edge map writing command to the writer.
   539     ///
   540    /// This function issues a new <i> edge map writing command</i> to the writer.
   541     template <typename Map>
   542     UndirGraphWriter& writeEdgeMap(std::string name, const Map& map) { 
   543       undir_edgeset_writer.writeEdgeMap(name, map);
   544       return *this;
   545     }
   546 
   547     /// \brief Issue a new edge map writing command to the writer.
   548     ///
   549    /// This function issues a new <i> edge map writing command</i> to the writer.
   550     template <typename Writer, typename Map>
   551     UndirGraphWriter& writeEdgeMap(std::string name, const Map& map,
   552 				   const Writer& writer = Writer()) {
   553       undir_edgeset_writer.writeEdgeMap(name, map, writer);
   554       return *this;
   555     }
   556 
   557     /// \brief Issue a new undirected edge map writing command to the writer.
   558     ///
   559     /// This function issues a new <i> undirected edge map writing
   560     /// command</i> to the writer.
   561     template <typename Map>
   562     UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map) { 
   563       undir_edgeset_writer.writeUndirEdgeMap(name, map);
   564       return *this;
   565     }
   566 
   567     /// \brief Issue a new undirected edge map writing command to the writer.
   568     ///
   569     /// This function issues a new <i> undirected edge map writing
   570     /// command</i> to the writer.
   571     template <typename Writer, typename Map>
   572     UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map,
   573 					const Writer& writer = Writer()) {
   574       undir_edgeset_writer.writeUndirEdgeMap(name, map, writer);
   575       return *this;
   576     }
   577 
   578     /// \brief Issue a new labeled node writer to the writer.
   579     ///
   580     /// This function issues a new <i> labeled node writing
   581     /// command</i> to the writer.
   582     UndirGraphWriter& writeNode(std::string name, const Node& node) {
   583       node_writer.writeNode(name, node);
   584       return *this;
   585     }
   586 
   587     /// \brief Issue a new labeled edge writer to the writer.
   588     ///
   589     /// This function issues a new <i> labeled edge writing
   590     /// command</i> to the writer.
   591     UndirGraphWriter& writeEdge(std::string name, const Edge& edge) {
   592       undir_edge_writer.writeEdge(name, edge);
   593     }
   594 
   595     /// \brief Issue a new labeled undirected edge writing command to
   596     /// the writer.
   597     ///
   598     /// Issue a new <i>labeled undirected edge writing command</i> to
   599     /// the writer.
   600     UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) {
   601       undir_edge_writer.writeUndirEdge(name, edge);
   602     }
   603 
   604     /// \brief Issue a new attribute writing command.
   605     ///
   606     /// This function issues a new <i> attribute writing
   607     /// command</i> to the writer.
   608     template <typename Value>
   609     UndirGraphWriter& writeAttribute(std::string name, const Value& value) {
   610       attribute_writer.writeAttribute(name, value);
   611       return *this;
   612     }
   613     
   614     /// \brief Issue a new attribute writing command.
   615     ///
   616     /// This function issues a new <i> attribute writing
   617     /// command</i> to the writer.
   618     template <typename Writer, typename Value>
   619     UndirGraphWriter& writeAttribute(std::string name, const Value& value, 
   620 			       const Writer& writer) {
   621       attribute_writer.writeAttribute<Writer>(name, value, writer);
   622       return *this;
   623     }
   624 
   625     /// \brief Conversion operator to LemonWriter.
   626     ///
   627     /// Conversion operator to LemonWriter. It makes possible
   628     /// to access the encapsulated \e LemonWriter, this way
   629     /// you can attach to this writer new instances of 
   630     /// \e LemonWriter::SectionWriter.
   631     operator LemonWriter&() {
   632       return *writer;
   633     }
   634 
   635     /// \brief Executes the writing commands.
   636     ///
   637     /// Executes the writing commands.
   638     void run() {
   639       writer->run();
   640     }
   641 
   642     /// \brief Write the id of the given node.
   643     ///
   644     /// It writes the id of the given node. If there was written an "id"
   645     /// named node map then it will write the map value belonging to the node.
   646     void writeId(std::ostream& os, const Node& item) const {
   647       nodeset_writer.writeId(os, item);
   648     } 
   649 
   650     /// \brief Write the id of the given edge.
   651     ///
   652     /// It writes the id of the given edge. If there was written an "id"
   653     /// named edge map then it will write the map value belonging to the edge.
   654     void writeId(std::ostream& os, const Edge& item) const {
   655       undir_edgeset_writer.writeId(os, item);
   656     } 
   657 
   658     /// \brief Write the id of the given undirected edge.
   659     ///
   660     /// It writes the id of the given undirected edge. If there was written 
   661     /// an "id" named edge map then it will write the map value belonging to 
   662     /// the edge.
   663     void writeId(std::ostream& os, const UndirEdge& item) const {
   664       undir_edgeset_writer.writeId(os, item);
   665     } 
   666 
   667 
   668   private:
   669 
   670     LemonWriter* writer;
   671     bool own_writer;
   672 
   673     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   674     UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer;
   675 
   676     NodeWriter<Graph> node_writer;
   677     UndirEdgeWriter<Graph> undir_edge_writer;
   678     
   679     AttributeWriter<WriterTraits> attribute_writer;
   680   };
   681 
   682   /// \brief Write an undirected graph to the output.
   683   ///
   684   /// Write an undirected graph to the output.
   685   /// \param os The output stream.
   686   /// \param g The graph.
   687   template<typename Graph>
   688   void writeUndirGraph(std::ostream& os, const Graph &g) {
   689     UndirGraphWriter<Graph> writer(os, g);
   690     writer.run();
   691   }
   692 
   693   /// \brief Write an undirected multigraph (undirected graph + capacity
   694   /// map on the edges) to the output.
   695   ///
   696   /// Write an undirected multigraph (undirected graph + capacity
   697   /// map on the edges) to the output.
   698   /// \param os The output stream.
   699   /// \param g The graph.
   700   /// \param capacity The capacity undirected map.
   701   template<typename Graph, typename CapacityMap>
   702   void writeUndirGraph(std::ostream& os, const Graph &g, 
   703 		       const CapacityMap& capacity) {
   704     UndirGraphWriter<Graph> writer(os, g);
   705     writer.writeUndirEdgeMap("capacity", capacity);
   706     writer.run();
   707   }
   708 
   709 
   710   /// @}
   711 
   712 }
   713 
   714 #endif