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