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