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