lemon/graph_writer.h
author deba
Tue, 22 Jul 2008 11:20:06 +0000
changeset 2616 02971275e7bf
parent 2502 9c23c3762bc5
permissions -rw-r--r--
Back port bug fix from hg changeset [0915721396dc]
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2008
     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 lemon_io
    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 lemon_io
    35   /// @{
    36 
    37   /// \brief The graph writer class.
    38   ///
    39   /// The \c GraphWriter class provides the graph output.  Before you
    40   /// read this documentation it might be useful to read the general
    41   /// description of \ref graph-io-page "Graph Input-Output".
    42   ///
    43   /// To write a graph you should first give writing commands to the
    44   /// writer. You can declare write commands as \c NodeMap or \c
    45   /// EdgeMap writing and labeled Node and Edge writing.
    46   ///
    47   ///\code
    48   /// GraphWriter<ListGraph> writer(std::cout, graph);
    49   ///\endcode
    50   ///
    51   /// The \c writeNodeMap() function declares a \c NodeMap writing
    52   /// command in the \c GraphWriter. You should give as parameter the
    53   /// name of the map and the map object. The NodeMap writing command
    54   /// with name "label" should write a unique map because it is
    55   /// regarded as label map (such a map is essential if the graph has
    56   /// edges).
    57   ///
    58   ///\code
    59   /// IdMap<ListGraph, Node> nodeLabelMap;
    60   /// writer.writeNodeMap("label", nodeLabelMap);
    61   ///
    62   /// writer.writeNodeMap("coords", coords);
    63   /// writer.writeNodeMap("color", colorMap);
    64   ///\endcode
    65   ///
    66   /// With the \c writeEdgeMap() member function you can give an edge map
    67   /// writing command similar to the NodeMaps.
    68   ///
    69   ///\code
    70   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
    71   ///   edgeDescMap(graph);
    72   /// writer.writeEdgeMap("descriptor", edgeDescMap);
    73   ///
    74   /// writer.writeEdgeMap("weight", weightMap);
    75   /// writer.writeEdgeMap("label", labelMap);
    76   ///\endcode
    77   ///
    78   /// With \c writeNode() and \c writeEdge() functions you can 
    79   /// point out Nodes and Edges in the graph. For example, you can 
    80   /// write out the source and target of a maximum flow instance.
    81   ///
    82   ///\code
    83   /// writer.writeNode("source", sourceNode);
    84   /// writer.writeNode("target", targetNode);
    85   ///
    86   /// writer.writeEdge("observed", edge);
    87   ///\endcode
    88   ///
    89   /// After you give all write commands you must call the \c run() member
    90   /// function, which executes all the writing commands.
    91   ///
    92   ///\code
    93   /// writer.run();
    94   ///\endcode
    95   ///
    96   /// \see DefaultWriterTraits
    97   /// \see QuotedStringWriter
    98   /// \see IdMap
    99   /// \see DescriptorMap
   100   /// \see \ref GraphReader
   101   /// \see \ref graph-io-page
   102   /// \author Balazs Dezso
   103   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   104   class GraphWriter {
   105   public:
   106     
   107     typedef _Graph Graph;
   108     typedef typename Graph::Node Node;
   109     typedef typename Graph::Edge Edge;
   110 
   111     typedef _WriterTraits WriterTraits;
   112 
   113     /// \brief Construct a new GraphWriter.
   114     ///
   115     /// This function constructs a new GraphWriter to write the given graph
   116     /// to the given stream.
   117     GraphWriter(std::ostream& _os, const Graph& _graph) 
   118       : writer(new LemonWriter(_os)), own_writer(true), 
   119 	nodeset_writer(*writer, _graph, std::string()),
   120 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   121 	node_writer(*writer, nodeset_writer, std::string()),
   122 	edge_writer(*writer, edgeset_writer, std::string()),
   123 	attribute_writer(*writer, std::string()) {}
   124 
   125     /// \brief Construct a new GraphWriter.
   126     ///
   127     /// This function constructs a new GraphWriter to write the given graph
   128     /// to the given file.
   129     GraphWriter(const std::string& _filename, const Graph& _graph) 
   130       : writer(new LemonWriter(_filename)), own_writer(true), 
   131 	nodeset_writer(*writer, _graph, std::string()),
   132 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   133 	node_writer(*writer, nodeset_writer, std::string()),
   134 	edge_writer(*writer, edgeset_writer, std::string()),
   135 	attribute_writer(*writer, std::string()) {}
   136 
   137     /// \brief Construct a new GraphWriter.
   138     ///
   139     /// This function constructs a new GraphWriter to write the given graph
   140     /// to the given LemonReader.
   141     GraphWriter(LemonWriter& _writer, const Graph& _graph)
   142       : writer(_writer), own_writer(false), 
   143 	nodeset_writer(*writer, _graph, std::string()),
   144 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   145 	node_writer(*writer, nodeset_writer, std::string()),
   146 	edge_writer(*writer, edgeset_writer, std::string()),
   147 	attribute_writer(*writer, std::string()) {}
   148 
   149     /// \brief Destruct the graph writer.
   150     ///
   151     /// This function destructs the graph writer.
   152     ~GraphWriter() {
   153       if (own_writer) 
   154 	delete writer;
   155     }
   156 
   157     /// \brief Issue a new node map writing command for the writer.
   158     ///
   159     /// This function issues a new <i> node map writing command</i> to the writer.
   160     template <typename Map>
   161     GraphWriter& writeNodeMap(std::string label, const Map& map) {
   162       nodeset_writer.writeNodeMap(label, map);
   163       return *this;
   164     }
   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 ItemWriter, typename Map>
   171     GraphWriter& writeNodeMap(std::string label, const Map& map, 
   172 			      const ItemWriter& iw = ItemWriter()) {
   173       nodeset_writer.writeNodeMap(label, map, iw);
   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 label, const Map& map) { 
   183       edgeset_writer.writeEdgeMap(label, 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 ItemWriter, typename Map>
   192     GraphWriter& writeEdgeMap(std::string label, const Map& map,
   193 			      const ItemWriter& iw = ItemWriter()) {
   194       edgeset_writer.writeEdgeMap(label, map, iw);
   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 label, const Node& node) {
   203       node_writer.writeNode(label, 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 label, const Edge& edge) {
   212       edge_writer.writeEdge(label, 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 label, const Value& value) {
   221       attribute_writer.writeAttribute(label, 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 ItemWriter, typename Value>
   230     GraphWriter& writeAttribute(std::string label, const Value& value, 
   231 			       const ItemWriter& iw = ItemWriter()) {
   232       attribute_writer.writeAttribute(label, value, iw);
   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. For more details see
   242     /// the \ref rwbackground "Background of Reading and Writing".
   243     operator LemonWriter&() {
   244       return *writer;
   245     }
   246 
   247     /// \brief Executes the writing commands.
   248     ///
   249     /// Executes the writing commands.
   250     void run() {
   251       writer->run();
   252     }
   253 
   254     /// \brief Returns true if the writer can give back the labels by the items.
   255     ///
   256     /// Returns true if the writer can give back the the labels by the items.
   257     bool isLabelWriter() const {
   258       return nodeset_writer.isLabelWriter() && 
   259         edgeset_writer.isLabelWriter();
   260     }
   261 
   262     /// \brief Write the label of the given node.
   263     ///
   264     /// It writes the label of the given node. If there was written a "label"
   265     /// named node map then it will write the map value belonging to the node.
   266     void writeLabel(std::ostream& os, const Node& item) const {
   267       nodeset_writer.writeLabel(os, item);
   268     } 
   269 
   270     /// \brief Write the label of the given edge.
   271     ///
   272     /// It writes the label of the given edge. If there was written a "label"
   273     /// named edge map then it will write the map value belonging to the edge.
   274     void writeLabel(std::ostream& os, const Edge& item) const {
   275       edgeset_writer.writeLabel(os, item);
   276     } 
   277 
   278     /// \brief Sorts the given node vector by label.
   279     ///
   280     /// Sorts the given node vector by label. If there was written an
   281     /// "label" named map then the vector will be sorted by the values
   282     /// of this map. Otherwise if the \c forceLabel parameter was true
   283     /// it will be sorted by its id in the graph.
   284     void sortByLabel(std::vector<Node>& nodes) const {
   285       nodeset_writer.sortByLabel(nodes);
   286     }
   287 
   288     /// \brief Sorts the given edge vector by label.
   289     ///
   290     /// Sorts the given edge vector by label. If there was written an
   291     /// "label" named map then the vector will be sorted by the values
   292     /// of this map. Otherwise if the \c forceLabel parameter was true
   293     /// it will be sorted by its id in the graph.
   294     void sortByLabel(std::vector<Edge>& edges) const {
   295       edgeset_writer.sortByLabel(edges);
   296     }
   297 
   298   private:
   299 
   300     LemonWriter* writer;
   301     bool own_writer;
   302 
   303     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   304     EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
   305 
   306     NodeWriter<Graph> node_writer;
   307     EdgeWriter<Graph> edge_writer;
   308     
   309     AttributeWriter<WriterTraits> attribute_writer;
   310   };
   311 
   312 
   313   /// \brief The undirected graph writer class.
   314   ///
   315   /// The \c UGraphWriter class provides the ugraph output. To write 
   316   /// a graph you should first give writing commands to the writer. You can 
   317   /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap 
   318   /// writing and labeled Node, Edge or UEdge writing.
   319   ///
   320   ///\code
   321   /// UGraphWriter<ListUGraph> writer(std::cout, graph);
   322   ///\endcode
   323   ///
   324   /// The \c writeNodeMap() function declares a \c NodeMap writing 
   325   /// command in the \c UGraphWriter. You should give as parameter 
   326   /// the name of the map and the map object. The NodeMap writing 
   327   /// command with name "label" should write a unique map because it 
   328   /// is regarded as label map.
   329   ///
   330   ///\code
   331   /// IdMap<ListUGraph, Node> nodeLabelMap;
   332   /// writer.writeNodeMap("label", nodeLabelMap);
   333   ///
   334   /// writer.writeNodeMap("coords", coords);
   335   /// writer.writeNodeMap("color", colorMap);
   336   ///\endcode
   337   ///
   338   /// With the \c writeUEdgeMap() member function you can give an 
   339   /// undirected edge map writing command similar to the NodeMaps.
   340   ///
   341   ///\code
   342   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
   343   ///   edgeDescMap(graph);
   344   /// writer.writeUEdgeMap("descriptor", edgeDescMap);
   345   ///
   346   /// writer.writeUEdgeMap("weight", weightMap);
   347   /// writer.writeUEdgeMap("label", labelMap);
   348   ///\endcode
   349   /// 
   350   /// The EdgeMap handling is just a syntactical sugar. It writes
   351   /// two undirected edge map with '+' and '-' prefix in the name.
   352   ///
   353   ///\code
   354   /// writer.writeEdgeMap("capacity", capacityMap);
   355   ///\endcode
   356   ///
   357   ///
   358   /// With \c writeNode() and \c writeUEdge() functions you can 
   359   /// designate nodes and undirected edges in the graph. For example, you can 
   360   /// write out the source and target of the graph.
   361   ///
   362   ///\code
   363   /// writer.writeNode("source", sourceNode);
   364   /// writer.writeNode("target", targetNode);
   365   ///
   366   /// writer.writeUEdge("observed", uEdge);
   367   ///\endcode
   368   ///
   369   /// After you give all write commands you must call the \c run() member
   370   /// function, which executes all the writing commands.
   371   ///
   372   ///\code
   373   /// writer.run();
   374   ///\endcode
   375   ///
   376   /// \see DefaultWriterTraits
   377   /// \see QuotedStringWriter
   378   /// \see IdMap
   379   /// \see DescriptorMap
   380   /// \see \ref GraphWriter
   381   /// \see \ref graph-io-page
   382   /// \author Balazs Dezso
   383   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   384   class UGraphWriter {
   385   public:
   386     
   387     typedef _Graph Graph;
   388     typedef typename Graph::Node Node;
   389     typedef typename Graph::Edge Edge;
   390     typedef typename Graph::UEdge UEdge;
   391 
   392     typedef _WriterTraits WriterTraits;
   393 
   394     /// \brief Construct a new UGraphWriter.
   395     ///
   396     /// Construct a new UGraphWriter. It writes the given graph
   397     /// to the given stream.
   398     UGraphWriter(std::ostream& _os, const Graph& _graph) 
   399       : writer(new LemonWriter(_os)), own_writer(true), 
   400 	nodeset_writer(*writer, _graph, std::string()),
   401 	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   402 	node_writer(*writer, nodeset_writer, std::string()),
   403 	uedge_writer(*writer, uedgeset_writer, std::string()),
   404 	attribute_writer(*writer, std::string()) {}
   405 
   406     /// \brief Construct a new UGraphWriter.
   407     ///
   408     /// Construct a new UGraphWriter. It writes the given graph
   409     /// to the given file.
   410     UGraphWriter(const std::string& _filename, const Graph& _graph) 
   411       : writer(new LemonWriter(_filename)), own_writer(true), 
   412 	nodeset_writer(*writer, _graph, std::string()),
   413 	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   414 	node_writer(*writer, nodeset_writer, std::string()),
   415 	uedge_writer(*writer, uedgeset_writer, std::string()),
   416 	attribute_writer(*writer, std::string()) {}
   417 
   418     /// \brief Construct a new UGraphWriter.
   419     ///
   420     /// Construct a new UGraphWriter. It writes the given graph
   421     /// to given LemonWriter.
   422     UGraphWriter(LemonWriter& _writer, const Graph& _graph)
   423       : writer(_writer), own_writer(false), 
   424 	nodeset_writer(*writer, _graph, std::string()),
   425 	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   426 	node_writer(*writer, nodeset_writer, std::string()),
   427 	uedge_writer(*writer, uedgeset_writer, std::string()),
   428 	attribute_writer(*writer, std::string()) {}
   429 
   430     /// \brief Destruct the graph writer.
   431     ///
   432     /// Destruct the graph writer.
   433     ~UGraphWriter() {
   434       if (own_writer) 
   435 	delete writer;
   436     }
   437 
   438     /// \brief Issue a new node map writing command to the writer.
   439     ///
   440     /// This function issues a new <i> node map writing command</i> to
   441     /// the writer.
   442     template <typename Map>
   443     UGraphWriter& writeNodeMap(std::string label, const Map& map) {
   444       nodeset_writer.writeNodeMap(label, map);
   445       return *this;
   446     }
   447 
   448     /// \brief Issue a new node map writing command to the writer.
   449     ///
   450     /// This function issues a new <i> node map writing command</i> to
   451     /// the writer.
   452     template <typename ItemWriter, typename Map>
   453     UGraphWriter& writeNodeMap(std::string label, const Map& map, 
   454 			      const ItemWriter& iw = ItemWriter()) {
   455       nodeset_writer.writeNodeMap(label, map, iw);
   456       return *this;
   457     }
   458 
   459     /// \brief Issue a new edge map writing command to the writer.
   460     ///
   461     /// This function issues a new <i> edge map writing command</i> to
   462     /// the writer.
   463     template <typename Map>
   464     UGraphWriter& writeEdgeMap(std::string label, const Map& map) { 
   465       uedgeset_writer.writeEdgeMap(label, map);
   466       return *this;
   467     }
   468 
   469     /// \brief Issue a new edge map writing command to the writer.
   470     ///
   471     /// This function issues a new <i> edge map writing command</i> to
   472     /// the writer.
   473     template <typename ItemWriter, typename Map>
   474     UGraphWriter& writeEdgeMap(std::string label, const Map& map,
   475 				   const ItemWriter& iw = ItemWriter()) {
   476       uedgeset_writer.writeEdgeMap(label, map, iw);
   477       return *this;
   478     }
   479 
   480     /// \brief Issue a new undirected edge map writing command to the writer.
   481     ///
   482     /// This function issues a new <i> undirected edge map writing
   483     /// command</i> to the writer.
   484     template <typename Map>
   485     UGraphWriter& writeUEdgeMap(std::string label, const Map& map) { 
   486       uedgeset_writer.writeUEdgeMap(label, map);
   487       return *this;
   488     }
   489 
   490     /// \brief Issue a new undirected edge map writing command to the writer.
   491     ///
   492     /// This function issues a new <i> undirected edge map writing
   493     /// command</i> to the writer.
   494    template <typename ItemWriter, typename Map>
   495     UGraphWriter& writeUEdgeMap(std::string label, const Map& map,
   496 					const ItemWriter& iw = ItemWriter()) {
   497       uedgeset_writer.writeUEdgeMap(label, map, iw);
   498       return *this;
   499     }
   500 
   501     /// \brief Issue a new labeled node writer to the writer.
   502     ///
   503     /// This function issues a new <i> labeled node writing
   504     /// command</i> to the writer.
   505     UGraphWriter& writeNode(std::string label, const Node& node) {
   506       node_writer.writeNode(label, node);
   507       return *this;
   508     }
   509 
   510     /// \brief Issue a new labeled edge writer to the writer.
   511     ///
   512     /// This function issues a new <i> labeled edge writing
   513     /// command</i> to the writer.
   514     UGraphWriter& writeEdge(std::string label, const Edge& edge) {
   515       uedge_writer.writeEdge(label, edge);
   516     }
   517 
   518     /// \brief Issue a new labeled undirected edge writing command to
   519     /// the writer.
   520     ///
   521     /// Issue a new <i>labeled undirected edge writing command</i> to
   522     /// the writer.
   523     UGraphWriter& writeUEdge(std::string label, const UEdge& edge) {
   524       uedge_writer.writeUEdge(label, edge);
   525     }
   526 
   527     /// \brief Issue a new attribute writing command.
   528     ///
   529     /// This function issues a new <i> attribute writing
   530     /// command</i> to the writer.
   531     template <typename Value>
   532     UGraphWriter& writeAttribute(std::string label, const Value& value) {
   533       attribute_writer.writeAttribute(label, value);
   534       return *this;
   535     }
   536     
   537     /// \brief Issue a new attribute writing command.
   538     ///
   539     /// This function issues a new <i> attribute writing
   540     /// command</i> to the writer.
   541     template <typename ItemWriter, typename Value>
   542     UGraphWriter& writeAttribute(std::string label, const Value& value, 
   543 			       const ItemWriter& iw = ItemWriter()) {
   544       attribute_writer.writeAttribute(label, value, iw);
   545       return *this;
   546     }
   547 
   548     /// \brief Conversion operator to LemonWriter.
   549     ///
   550     /// Conversion operator to LemonWriter. It makes possible
   551     /// to access the encapsulated \e LemonWriter, this way
   552     /// you can attach to this writer new instances of 
   553     /// \e LemonWriter::SectionWriter.
   554     operator LemonWriter&() {
   555       return *writer;
   556     }
   557 
   558     /// \brief Executes the writing commands.
   559     ///
   560     /// Executes the writing commands.
   561     void run() {
   562       writer->run();
   563     }
   564 
   565     /// \brief Returns true if the writer can give back the labels by the items.
   566     ///
   567     /// Returns true if the writer can give back the the labels by the items.
   568     bool isLabelWriter() const {
   569       return nodeset_writer.isLabelWriter() && 
   570         uedgeset_writer.isLabelWriter();
   571     }
   572 
   573     /// \brief Write the label of the given node.
   574     ///
   575     /// It writes the label of the given node. If there was written a "label"
   576     /// named node map then it will write the map value belonging to the node.
   577     void writeLabel(std::ostream& os, const Node& item) const {
   578       nodeset_writer.writeLabel(os, item);
   579     } 
   580 
   581     /// \brief Write the label of the given edge.
   582     ///
   583     /// It writes the label of the given edge. If there was written a "label"
   584     /// named edge map then it will write the map value belonging to the edge.
   585     void writeLabel(std::ostream& os, const Edge& item) const {
   586       uedgeset_writer.writeLabel(os, item);
   587     } 
   588 
   589     /// \brief Write the label of the given undirected edge.
   590     ///
   591     /// It writes the label of the given undirected edge. If there was
   592     /// written a "label" named edge map then it will write the map
   593     /// value belonging to the edge.
   594     void writeLabel(std::ostream& os, const UEdge& item) const {
   595       uedgeset_writer.writeLabel(os, item);
   596     } 
   597 
   598     /// \brief Sorts the given node vector by label.
   599     ///
   600     /// Sorts the given node vector by label. If there was written an
   601     /// "label" named map then the vector will be sorted by the values
   602     /// of this map. Otherwise if the \c forceLabel parameter was true
   603     /// it will be sorted by its id in the graph.
   604     void sortByLabel(std::vector<Node>& nodes) const {
   605       nodeset_writer.sortByLabel(nodes);
   606     }
   607 
   608     /// \brief Sorts the given edge vector by label.
   609     ///
   610     /// Sorts the given edge vector by label. If there was written an
   611     /// "label" named map then the vector will be sorted by the values
   612     /// of this map. Otherwise if the \c forceLabel parameter was true
   613     /// it will be sorted by its id in the graph.
   614     void sortByLabel(std::vector<Edge>& edges) const {
   615       uedgeset_writer.sortByLabel(edges);
   616     }
   617 
   618     /// \brief Sorts the given undirected edge vector by label.
   619     ///
   620     /// Sorts the given undirected edge vector by label. If there was
   621     /// written an "label" named map then the vector will be sorted by
   622     /// the values of this map. Otherwise if the \c forceLabel
   623     /// parameter was true it will be sorted by its id in the graph.
   624     void sortByLabel(std::vector<UEdge>& uedges) const {
   625       uedgeset_writer.sortByLabel(uedges);
   626     }
   627 
   628   private:
   629 
   630     LemonWriter* writer;
   631     bool own_writer;
   632 
   633     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   634     UEdgeSetWriter<Graph, WriterTraits> uedgeset_writer;
   635 
   636     NodeWriter<Graph> node_writer;
   637     UEdgeWriter<Graph> uedge_writer;
   638     
   639     AttributeWriter<WriterTraits> attribute_writer;
   640   };
   641 
   642   /// \brief The bipartite graph writer class.
   643   ///
   644   /// The \c BpUGraphWriter class provides the ugraph output. To write 
   645   /// a graph you should first give writing commands to the writer. You can 
   646   /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap 
   647   /// writing and labeled Node, Edge or UEdge writing.
   648   ///
   649   ///\code
   650   /// BpUGraphWriter<ListUGraph> writer(std::cout, graph);
   651   ///\endcode
   652   ///
   653   /// The \c writeNodeMap() function declares a \c NodeMap writing 
   654   /// command in the \c BpUGraphWriter. You should give as parameter 
   655   /// the name of the map and the map object. The NodeMap writing 
   656   /// command with name "label" should write a unique map because it 
   657   /// is regarded as label map.
   658   ///
   659   ///\code
   660   /// IdMap<ListUGraph, Node> nodeLabelMap;
   661   /// writer.writeNodeMap("label", nodeLabelMap);
   662   ///
   663   /// writer.writeNodeMap("coords", coords);
   664   /// writer.writeNodeMap("color", colorMap);
   665   ///\endcode
   666   ///
   667   /// With the \c writeUEdgeMap() member function you can give an 
   668   /// undirected edge map writing command similar to the NodeMaps.
   669   ///
   670   ///\code
   671   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
   672   ///   edgeDescMap(graph);
   673   /// writer.writeUEdgeMap("descriptor", edgeDescMap);
   674   ///
   675   /// writer.writeUEdgeMap("weight", weightMap);
   676   /// writer.writeUEdgeMap("label", labelMap);
   677   ///\endcode
   678   /// 
   679   /// The EdgeMap handling is just a syntactical sugar. It writes
   680   /// two undirected edge map with '+' and '-' prefix in the name.
   681   ///
   682   ///\code
   683   /// writer.writeEdgeMap("capacity", capacityMap);
   684   ///\endcode
   685   ///
   686   ///
   687   /// With \c writeNode() and \c writeUEdge() functions you can 
   688   /// designate nodes and undirected edges in the graph. For example, you can 
   689   /// write out the source and target of the graph.
   690   ///
   691   ///\code
   692   /// writer.writeNode("source", sourceNode);
   693   /// writer.writeNode("target", targetNode);
   694   ///
   695   /// writer.writeUEdge("observed", uEdge);
   696   ///\endcode
   697   ///
   698   /// After you give all write commands you must call the \c run() member
   699   /// function, which executes all the writing commands.
   700   ///
   701   ///\code
   702   /// writer.run();
   703   ///\endcode
   704   ///
   705   /// \see DefaultWriterTraits
   706   /// \see QuotedStringWriter
   707   /// \see IdMap
   708   /// \see DescriptorMap
   709   /// \see \ref GraphWriter
   710   /// \see \ref graph-io-page
   711   /// \author Balazs Dezso
   712   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   713   class BpUGraphWriter {
   714   public:
   715     
   716     typedef _Graph Graph;
   717     typedef typename Graph::Node Node;
   718     typedef typename Graph::Edge Edge;
   719     typedef typename Graph::UEdge UEdge;
   720 
   721     typedef _WriterTraits WriterTraits;
   722 
   723     /// \brief Construct a new BpUGraphWriter.
   724     ///
   725     /// Construct a new BpUGraphWriter. It writes the given graph
   726     /// to the given stream.
   727     BpUGraphWriter(std::ostream& _os, const Graph& _graph) 
   728       : writer(new LemonWriter(_os)), own_writer(true), 
   729 	nodeset_writer(*writer, _graph, std::string()),
   730 	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   731 	node_writer(*writer, nodeset_writer, std::string()),
   732 	uedge_writer(*writer, uedgeset_writer, std::string()),
   733 	attribute_writer(*writer, std::string()) {}
   734 
   735     /// \brief Construct a new BpUGraphWriter.
   736     ///
   737     /// Construct a new BpUGraphWriter. It writes the given graph
   738     /// to the given file.
   739     BpUGraphWriter(const std::string& _filename, const Graph& _graph) 
   740       : writer(new LemonWriter(_filename)), own_writer(true), 
   741 	nodeset_writer(*writer, _graph, std::string()),
   742 	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   743 	node_writer(*writer, nodeset_writer, std::string()),
   744 	uedge_writer(*writer, uedgeset_writer, std::string()),
   745 	attribute_writer(*writer, std::string()) {}
   746 
   747     /// \brief Construct a new BpUGraphWriter.
   748     ///
   749     /// Construct a new BpUGraphWriter. It writes the given graph
   750     /// to given LemonWriter.
   751     BpUGraphWriter(LemonWriter& _writer, const Graph& _graph)
   752       : writer(_writer), own_writer(false), 
   753 	nodeset_writer(*writer, _graph, std::string()),
   754 	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   755 	node_writer(*writer, nodeset_writer, std::string()),
   756 	uedge_writer(*writer, uedgeset_writer, std::string()),
   757 	attribute_writer(*writer, std::string()) {}
   758 
   759     /// \brief Destruct the graph writer.
   760     ///
   761     /// Destruct the graph writer.
   762     ~BpUGraphWriter() {
   763       if (own_writer) 
   764 	delete writer;
   765     }
   766 
   767     /// \brief Issue a new node map writing command to the writer.
   768     ///
   769     /// This function issues a new <i> node map writing command</i> to
   770     /// the writer.
   771     template <typename Map>
   772     BpUGraphWriter& writeNodeMap(std::string label, const Map& map) {
   773       nodeset_writer.writeNodeMap(label, map);
   774       return *this;
   775     }
   776 
   777     /// \brief Issue a new node map writing command to the writer.
   778     ///
   779     /// This function issues a new <i> node map writing command</i> to
   780     /// the writer.
   781     template <typename ItemWriter, typename Map>
   782     BpUGraphWriter& writeNodeMap(std::string label, const Map& map, 
   783 			      const ItemWriter& iw = ItemWriter()) {
   784       nodeset_writer.writeNodeMap(label, map, iw);
   785       return *this;
   786     }
   787 
   788     /// \brief Issue a new A-node map writing command to the writer.
   789     ///
   790     /// This function issues a new <i> A-node map writing command</i> to
   791     /// the writer.
   792     template <typename Map>
   793     BpUGraphWriter& writeANodeMap(std::string label, const Map& map) {
   794       nodeset_writer.writeANodeMap(label, map);
   795       return *this;
   796     }
   797 
   798     /// \brief Issue a new A-node map writing command to the writer.
   799     ///
   800     /// This function issues a new <i> A-node map writing command</i> to
   801     /// the writer.
   802     template <typename ItemWriter, typename Map>
   803     BpUGraphWriter& writeANodeMap(std::string label, const Map& map, 
   804 			      const ItemWriter& iw = ItemWriter()) {
   805       nodeset_writer.writeANodeMap(label, map, iw);
   806       return *this;
   807     }
   808     /// \brief Issue a new B-node map writing command to the writer.
   809     ///
   810     /// This function issues a new <i> B-node map writing command</i> to
   811     /// the writer.
   812     template <typename Map>
   813     BpUGraphWriter& writeBNodeMap(std::string label, const Map& map) {
   814       nodeset_writer.writeBNodeMap(label, map);
   815       return *this;
   816     }
   817 
   818     /// \brief Issue a new B-node map writing command to the writer.
   819     ///
   820     /// This function issues a new <i> B-node map writing command</i> to
   821     /// the writer.
   822     template <typename ItemWriter, typename Map>
   823     BpUGraphWriter& writeBNodeMap(std::string label, const Map& map, 
   824 			      const ItemWriter& iw = ItemWriter()) {
   825       nodeset_writer.writeBNodeMap(label, map, iw);
   826       return *this;
   827     }
   828 
   829     /// \brief Issue a new edge map writing command to the writer.
   830     ///
   831     /// This function issues a new <i> edge map writing command</i> to
   832     /// the writer.
   833     template <typename Map>
   834     BpUGraphWriter& writeEdgeMap(std::string label, const Map& map) { 
   835       uedgeset_writer.writeEdgeMap(label, map);
   836       return *this;
   837     }
   838 
   839     /// \brief Issue a new edge map writing command to the writer.
   840     ///
   841     /// This function issues a new <i> edge map writing command</i> to
   842     /// the writer.
   843     template <typename ItemWriter, typename Map>
   844     BpUGraphWriter& writeEdgeMap(std::string label, const Map& map,
   845 				   const ItemWriter& iw = ItemWriter()) {
   846       uedgeset_writer.writeEdgeMap(label, map, iw);
   847       return *this;
   848     }
   849 
   850     /// \brief Issue a new undirected edge map writing command to the writer.
   851     ///
   852     /// This function issues a new <i> undirected edge map writing
   853     /// command</i> to the writer.
   854     template <typename Map>
   855     BpUGraphWriter& writeUEdgeMap(std::string label, const Map& map) { 
   856       uedgeset_writer.writeUEdgeMap(label, map);
   857       return *this;
   858     }
   859 
   860     /// \brief Issue a new undirected edge map writing command to the writer.
   861     ///
   862     /// This function issues a new <i> undirected edge map writing
   863     /// command</i> to the writer.
   864    template <typename ItemWriter, typename Map>
   865     BpUGraphWriter& writeUEdgeMap(std::string label, const Map& map,
   866 					const ItemWriter& iw = ItemWriter()) {
   867       uedgeset_writer.writeUEdgeMap(label, map, iw);
   868       return *this;
   869     }
   870 
   871     /// \brief Issue a new labeled node writer to the writer.
   872     ///
   873     /// This function issues a new <i> labeled node writing
   874     /// command</i> to the writer.
   875     BpUGraphWriter& writeNode(std::string label, const Node& node) {
   876       node_writer.writeNode(label, node);
   877       return *this;
   878     }
   879 
   880     /// \brief Issue a new labeled edge writer to the writer.
   881     ///
   882     /// This function issues a new <i> labeled edge writing
   883     /// command</i> to the writer.
   884     BpUGraphWriter& writeEdge(std::string label, const Edge& edge) {
   885       uedge_writer.writeEdge(label, edge);
   886     }
   887 
   888     /// \brief Issue a new labeled undirected edge writing command to
   889     /// the writer.
   890     ///
   891     /// Issue a new <i>labeled undirected edge writing command</i> to
   892     /// the writer.
   893     BpUGraphWriter& writeUEdge(std::string label, const UEdge& edge) {
   894       uedge_writer.writeUEdge(label, edge);
   895     }
   896 
   897     /// \brief Issue a new attribute writing command.
   898     ///
   899     /// This function issues a new <i> attribute writing
   900     /// command</i> to the writer.
   901     template <typename Value>
   902     BpUGraphWriter& writeAttribute(std::string label, const Value& value) {
   903       attribute_writer.writeAttribute(label, value);
   904       return *this;
   905     }
   906     
   907     /// \brief Issue a new attribute writing command.
   908     ///
   909     /// This function issues a new <i> attribute writing
   910     /// command</i> to the writer.
   911     template <typename ItemWriter, typename Value>
   912     BpUGraphWriter& writeAttribute(std::string label, const Value& value, 
   913 			       const ItemWriter& iw = ItemWriter()) {
   914       attribute_writer.writeAttribute(label, value, iw);
   915       return *this;
   916     }
   917 
   918     /// \brief Conversion operator to LemonWriter.
   919     ///
   920     /// Conversion operator to LemonWriter. It makes possible
   921     /// to access the encapsulated \e LemonWriter, this way
   922     /// you can attach to this writer new instances of 
   923     /// \e LemonWriter::SectionWriter.
   924     operator LemonWriter&() {
   925       return *writer;
   926     }
   927 
   928     /// \brief Executes the writing commands.
   929     ///
   930     /// Executes the writing commands.
   931     void run() {
   932       writer->run();
   933     }
   934 
   935     /// \brief Returns true if the writer can give back the labels by the items.
   936     ///
   937     /// Returns true if the writer can give back the the labels by the items.
   938     bool isLabelWriter() const {
   939       return nodeset_writer.isLabelWriter() && 
   940         uedgeset_writer.isLabelWriter();
   941     }
   942 
   943     /// \brief Write the label of the given node.
   944     ///
   945     /// It writes the label of the given node. If there was written a "label"
   946     /// named node map then it will write the map value belonging to the node.
   947     void writeLabel(std::ostream& os, const Node& item) const {
   948       nodeset_writer.writeLabel(os, item);
   949     } 
   950 
   951     /// \brief Write the label of the given edge.
   952     ///
   953     /// It writes the label of the given edge. If there was written a "label"
   954     /// named edge map then it will write the map value belonging to the edge.
   955     void writeLabel(std::ostream& os, const Edge& item) const {
   956       uedgeset_writer.writeLabel(os, item);
   957     } 
   958 
   959     /// \brief Write the label of the given undirected edge.
   960     ///
   961     /// It writes the label of the given undirected edge. If there was
   962     /// written a "label" named edge map then it will write the map
   963     /// value belonging to the edge.
   964     void writeLabel(std::ostream& os, const UEdge& item) const {
   965       uedgeset_writer.writeLabel(os, item);
   966     } 
   967 
   968     /// \brief Sorts the given node vector by label.
   969     ///
   970     /// Sorts the given node vector by label. If there was written an
   971     /// "label" named map then the vector will be sorted by the values
   972     /// of this map. Otherwise if the \c forceLabel parameter was true
   973     /// it will be sorted by its id in the graph.
   974     void sortByLabel(std::vector<Node>& nodes) const {
   975       nodeset_writer.sortByLabel(nodes);
   976     }
   977 
   978     /// \brief Sorts the given edge vector by label.
   979     ///
   980     /// Sorts the given edge vector by label. If there was written an
   981     /// "label" named map then the vector will be sorted by the values
   982     /// of this map. Otherwise if the \c forceLabel parameter was true
   983     /// it will be sorted by its id in the graph.
   984     void sortByLabel(std::vector<Edge>& edges) const {
   985       uedgeset_writer.sortByLabel(edges);
   986     }
   987 
   988     /// \brief Sorts the given undirected edge vector by label.
   989     ///
   990     /// Sorts the given undirected edge vector by label. If there was
   991     /// written an "label" named map then the vector will be sorted by
   992     /// the values of this map. Otherwise if the \c forceLabel
   993     /// parameter was true it will be sorted by its id in the graph.
   994     void sortByLabel(std::vector<UEdge>& uedges) const {
   995       uedgeset_writer.sortByLabel(uedges);
   996     }
   997 
   998   private:
   999 
  1000     LemonWriter* writer;
  1001     bool own_writer;
  1002 
  1003     BpNodeSetWriter<Graph, WriterTraits> nodeset_writer;
  1004     UEdgeSetWriter<Graph, WriterTraits> uedgeset_writer;
  1005 
  1006     NodeWriter<Graph> node_writer;
  1007     UEdgeWriter<Graph> uedge_writer;
  1008     
  1009     AttributeWriter<WriterTraits> attribute_writer;
  1010   };
  1011 
  1012   /// @}
  1013 
  1014 }
  1015 
  1016 #endif