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