src/lemon/graph_writer.h
changeset 1435 8e85e6bbefdf
parent 1421 7a21e1414c38
equal deleted inserted replaced
18:62d2fe26cbda -1:000000000000
     1 /* -*- C++ -*-
       
     2  * src/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