lemon/graph_writer.h
author deba
Wed, 07 Mar 2007 11:56:14 +0000
changeset 2396 658c04d74729
parent 2386 81b47fc5c444
child 2467 2025a571895e
permissions -rw-r--r--
naming convention:
header sentry
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2007
     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 Write the label of the given node.
   255     ///
   256     /// It writes the label of the given node. If there was written an "label"
   257     /// named node map then it will write the map value belonging to the node.
   258     void writeLabel(std::ostream& os, const Node& item) const {
   259       nodeset_writer.writeLabel(os, item);
   260     } 
   261 
   262     /// \brief Write the label of the given edge.
   263     ///
   264     /// It writes the label of the given edge. If there was written an "label"
   265     /// named edge map then it will write the map value belonging to the edge.
   266     void writeLabel(std::ostream& os, const Edge& item) const {
   267       edgeset_writer.writeLabel(os, item);
   268     } 
   269 
   270   private:
   271 
   272     LemonWriter* writer;
   273     bool own_writer;
   274 
   275     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   276     EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
   277 
   278     NodeWriter<Graph> node_writer;
   279     EdgeWriter<Graph> edge_writer;
   280     
   281     AttributeWriter<WriterTraits> attribute_writer;
   282   };
   283 
   284 
   285   /// \brief The undirected graph writer class.
   286   ///
   287   /// The \c UGraphWriter class provides the ugraph output. To write 
   288   /// a graph you should first give writing commands to the writer. You can 
   289   /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap 
   290   /// writing and labeled Node, Edge or UEdge writing.
   291   ///
   292   ///\code
   293   /// UGraphWriter<ListUGraph> writer(std::cout, graph);
   294   ///\endcode
   295   ///
   296   /// The \c writeNodeMap() function declares a \c NodeMap writing 
   297   /// command in the \c UGraphWriter. You should give as parameter 
   298   /// the name of the map and the map object. The NodeMap writing 
   299   /// command with name "label" should write a unique map because it 
   300   /// is regarded as label map.
   301   ///
   302   ///\code
   303   /// IdMap<ListUGraph, Node> nodeLabelMap;
   304   /// writer.writeNodeMap("label", nodeLabelMap);
   305   ///
   306   /// writer.writeNodeMap("coords", coords);
   307   /// writer.writeNodeMap("color", colorMap);
   308   ///\endcode
   309   ///
   310   /// With the \c writeUEdgeMap() member function you can give an 
   311   /// undirected edge map writing command similar to the NodeMaps.
   312   ///
   313   ///\code
   314   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
   315   ///   edgeDescMap(graph);
   316   /// writer.writeUEdgeMap("descriptor", edgeDescMap);
   317   ///
   318   /// writer.writeUEdgeMap("weight", weightMap);
   319   /// writer.writeUEdgeMap("label", labelMap);
   320   ///\endcode
   321   /// 
   322   /// The EdgeMap handling is just a syntactical sugar. It writes
   323   /// two undirected edge map with '+' and '-' prefix in the name.
   324   ///
   325   ///\code
   326   /// writer.writeEdgeMap("capacity", capacityMap);
   327   ///\endcode
   328   ///
   329   ///
   330   /// With \c writeNode() and \c writeUEdge() functions you can 
   331   /// designate nodes and undirected edges in the graph. For example, you can 
   332   /// write out the source and target of the graph.
   333   ///
   334   ///\code
   335   /// writer.writeNode("source", sourceNode);
   336   /// writer.writeNode("target", targetNode);
   337   ///
   338   /// writer.writeUEdge("observed", uEdge);
   339   ///\endcode
   340   ///
   341   /// After you give all write commands you must call the \c run() member
   342   /// function, which executes all the writing commands.
   343   ///
   344   ///\code
   345   /// writer.run();
   346   ///\endcode
   347   ///
   348   /// \see DefaultWriterTraits
   349   /// \see QuotedStringWriter
   350   /// \see IdMap
   351   /// \see DescriptorMap
   352   /// \see \ref GraphWriter
   353   /// \see \ref graph-io-page
   354   /// \author Balazs Dezso
   355   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   356   class UGraphWriter {
   357   public:
   358     
   359     typedef _Graph Graph;
   360     typedef typename Graph::Node Node;
   361     typedef typename Graph::Edge Edge;
   362     typedef typename Graph::UEdge UEdge;
   363 
   364     typedef _WriterTraits WriterTraits;
   365 
   366     /// \brief Construct a new UGraphWriter.
   367     ///
   368     /// Construct a new UGraphWriter. It writes the given graph
   369     /// to the given stream.
   370     UGraphWriter(std::ostream& _os, const Graph& _graph) 
   371       : writer(new LemonWriter(_os)), own_writer(true), 
   372 	nodeset_writer(*writer, _graph, std::string()),
   373 	u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   374 	node_writer(*writer, nodeset_writer, std::string()),
   375 	u_edge_writer(*writer, u_edgeset_writer, std::string()),
   376 	attribute_writer(*writer, std::string()) {}
   377 
   378     /// \brief Construct a new UGraphWriter.
   379     ///
   380     /// Construct a new UGraphWriter. It writes the given graph
   381     /// to the given file.
   382     UGraphWriter(const std::string& _filename, const Graph& _graph) 
   383       : writer(new LemonWriter(_filename)), own_writer(true), 
   384 	nodeset_writer(*writer, _graph, std::string()),
   385 	u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   386 	node_writer(*writer, nodeset_writer, std::string()),
   387 	u_edge_writer(*writer, u_edgeset_writer, std::string()),
   388 	attribute_writer(*writer, std::string()) {}
   389 
   390     /// \brief Construct a new UGraphWriter.
   391     ///
   392     /// Construct a new UGraphWriter. It writes the given graph
   393     /// to given LemonReader.
   394     UGraphWriter(LemonWriter& _writer, const Graph& _graph)
   395       : writer(_writer), own_writer(false), 
   396 	nodeset_writer(*writer, _graph, std::string()),
   397 	u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   398 	node_writer(*writer, nodeset_writer, std::string()),
   399 	u_edge_writer(*writer, u_edgeset_writer, std::string()),
   400 	attribute_writer(*writer, std::string()) {}
   401 
   402     /// \brief Destruct the graph writer.
   403     ///
   404     /// Destruct the graph writer.
   405     ~UGraphWriter() {
   406       if (own_writer) 
   407 	delete writer;
   408     }
   409 
   410     /// \brief Issue a new node map writing command to the writer.
   411     ///
   412     /// This function issues a new <i> node map writing command</i> to
   413     /// the writer.
   414     template <typename Map>
   415     UGraphWriter& writeNodeMap(std::string label, const Map& map) {
   416       nodeset_writer.writeNodeMap(label, map);
   417       return *this;
   418     }
   419 
   420     /// \brief Issue a new node map writing command to the writer.
   421     ///
   422     /// This function issues a new <i> node map writing command</i> to
   423     /// the writer.
   424     template <typename ItemWriter, typename Map>
   425     UGraphWriter& writeNodeMap(std::string label, const Map& map, 
   426 			      const ItemWriter& iw = ItemWriter()) {
   427       nodeset_writer.writeNodeMap(label, map, iw);
   428       return *this;
   429     }
   430 
   431     /// \brief Issue a new edge map writing command to the writer.
   432     ///
   433     /// This function issues a new <i> edge map writing command</i> to
   434     /// the writer.
   435     template <typename Map>
   436     UGraphWriter& writeEdgeMap(std::string label, const Map& map) { 
   437       u_edgeset_writer.writeEdgeMap(label, map);
   438       return *this;
   439     }
   440 
   441     /// \brief Issue a new edge map writing command to the writer.
   442     ///
   443     /// This function issues a new <i> edge map writing command</i> to
   444     /// the writer.
   445     template <typename ItemWriter, typename Map>
   446     UGraphWriter& writeEdgeMap(std::string label, const Map& map,
   447 				   const ItemWriter& iw = ItemWriter()) {
   448       u_edgeset_writer.writeEdgeMap(label, map, iw);
   449       return *this;
   450     }
   451 
   452     /// \brief Issue a new undirected edge map writing command to the writer.
   453     ///
   454     /// This function issues a new <i> undirected edge map writing
   455     /// command</i> to the writer.
   456     template <typename Map>
   457     UGraphWriter& writeUEdgeMap(std::string label, const Map& map) { 
   458       u_edgeset_writer.writeUEdgeMap(label, map);
   459       return *this;
   460     }
   461 
   462     /// \brief Issue a new undirected edge map writing command to the writer.
   463     ///
   464     /// This function issues a new <i> undirected edge map writing
   465     /// command</i> to the writer.
   466    template <typename ItemWriter, typename Map>
   467     UGraphWriter& writeUEdgeMap(std::string label, const Map& map,
   468 					const ItemWriter& iw = ItemWriter()) {
   469       u_edgeset_writer.writeUEdgeMap(label, map, iw);
   470       return *this;
   471     }
   472 
   473     /// \brief Issue a new labeled node writer to the writer.
   474     ///
   475     /// This function issues a new <i> labeled node writing
   476     /// command</i> to the writer.
   477     UGraphWriter& writeNode(std::string label, const Node& node) {
   478       node_writer.writeNode(label, node);
   479       return *this;
   480     }
   481 
   482     /// \brief Issue a new labeled edge writer to the writer.
   483     ///
   484     /// This function issues a new <i> labeled edge writing
   485     /// command</i> to the writer.
   486     UGraphWriter& writeEdge(std::string label, const Edge& edge) {
   487       u_edge_writer.writeEdge(label, edge);
   488     }
   489 
   490     /// \brief Issue a new labeled undirected edge writing command to
   491     /// the writer.
   492     ///
   493     /// Issue a new <i>labeled undirected edge writing command</i> to
   494     /// the writer.
   495     UGraphWriter& writeUEdge(std::string label, const UEdge& edge) {
   496       u_edge_writer.writeUEdge(label, edge);
   497     }
   498 
   499     /// \brief Issue a new attribute writing command.
   500     ///
   501     /// This function issues a new <i> attribute writing
   502     /// command</i> to the writer.
   503     template <typename Value>
   504     UGraphWriter& writeAttribute(std::string label, const Value& value) {
   505       attribute_writer.writeAttribute(label, value);
   506       return *this;
   507     }
   508     
   509     /// \brief Issue a new attribute writing command.
   510     ///
   511     /// This function issues a new <i> attribute writing
   512     /// command</i> to the writer.
   513     template <typename ItemWriter, typename Value>
   514     UGraphWriter& writeAttribute(std::string label, const Value& value, 
   515 			       const ItemWriter& iw = ItemWriter()) {
   516       attribute_writer.writeAttribute(label, value, iw);
   517       return *this;
   518     }
   519 
   520     /// \brief Conversion operator to LemonWriter.
   521     ///
   522     /// Conversion operator to LemonWriter. It makes possible
   523     /// to access the encapsulated \e LemonWriter, this way
   524     /// you can attach to this writer new instances of 
   525     /// \e LemonWriter::SectionWriter.
   526     operator LemonWriter&() {
   527       return *writer;
   528     }
   529 
   530     /// \brief Executes the writing commands.
   531     ///
   532     /// Executes the writing commands.
   533     void run() {
   534       writer->run();
   535     }
   536 
   537     /// \brief Write the label of the given node.
   538     ///
   539     /// It writes the label of the given node. If there was written an "label"
   540     /// named node map then it will write the map value belonging to the node.
   541     void writeLabel(std::ostream& os, const Node& item) const {
   542       nodeset_writer.writeLabel(os, item);
   543     } 
   544 
   545     /// \brief Write the label of the given edge.
   546     ///
   547     /// It writes the label of the given edge. If there was written an "label"
   548     /// named edge map then it will write the map value belonging to the edge.
   549     void writeLabel(std::ostream& os, const Edge& item) const {
   550       u_edgeset_writer.writeLabel(os, item);
   551     } 
   552 
   553     /// \brief Write the label of the given undirected edge.
   554     ///
   555     /// It writes the label of the given undirected edge. If there was
   556     /// written an "label" named edge map then it will write the map
   557     /// value belonging to the edge.
   558     void writeLabel(std::ostream& os, const UEdge& item) const {
   559       u_edgeset_writer.writeLabel(os, item);
   560     } 
   561 
   562 
   563   private:
   564 
   565     LemonWriter* writer;
   566     bool own_writer;
   567 
   568     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   569     UEdgeSetWriter<Graph, WriterTraits> u_edgeset_writer;
   570 
   571     NodeWriter<Graph> node_writer;
   572     UEdgeWriter<Graph> u_edge_writer;
   573     
   574     AttributeWriter<WriterTraits> attribute_writer;
   575   };
   576 
   577   /// @}
   578 
   579 }
   580 
   581 #endif