src/lemon/graph_writer.h
author deba
Sat, 14 May 2005 17:32:11 +0000
changeset 1418 afaa773d0ad0
parent 1409 d2d1f8fa187b
child 1421 7a21e1414c38
permissions -rw-r--r--
Handling smarter the references
It's used by the lemon IO and proposed by the adaptors.
deba@1137
     1
/* -*- C++ -*-
deba@1137
     2
 * src/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@1394
    55
  /// writer.writeNodeMap("x-coord", xCoordMap);
deba@1394
    56
  /// writer.writeNodeMap("y-coord", yCoordMap);
deba@1394
    57
  /// writer.writeNodeMap("color", colorMap);
deba@1333
    58
  /// \endcode
deba@1333
    59
  ///
deba@1394
    60
  /// With the \c writeEdgeMap() member function you can give an edge map
deba@1333
    61
  /// writing command similar to the NodeMaps.
deba@1333
    62
  ///
deba@1333
    63
  /// \code
deba@1333
    64
  /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
deba@1333
    65
  ///   edgeDescMap(graph);
deba@1394
    66
  /// writer.writeEdgeMap("descriptor", edgeDescMap);
deba@1333
    67
  ///
deba@1394
    68
  /// writer.writeEdgeMap("weight", weightMap);
deba@1394
    69
  /// writer.writeEdgeMap("label", labelMap);
deba@1333
    70
  /// \endcode
deba@1333
    71
  ///
deba@1394
    72
  /// With \c writeNode() and \c writeEdge() functions you can 
deba@1394
    73
  /// point out Nodes and Edges in the graph. By example, you can 
deba@1394
    74
  /// write out the source and target of the graph.
deba@1333
    75
  ///
deba@1333
    76
  /// \code
deba@1394
    77
  /// writer.writeNode("source", sourceNode);
deba@1394
    78
  /// writer.writeNode("target", targetNode);
deba@1333
    79
  ///
deba@1394
    80
  /// writer.writeEdge("observed", edge);
deba@1333
    81
  /// \endcode
deba@1333
    82
  ///
deba@1333
    83
  /// After you give all write commands you must call the \c run() member
deba@1333
    84
  /// function, which execute all the writer commands.
deba@1333
    85
  ///
deba@1333
    86
  /// \code
deba@1333
    87
  /// writer.run();
deba@1333
    88
  /// \endcode
deba@1333
    89
  ///
alpar@1287
    90
  /// \see DefaultWriterTraits
alpar@1287
    91
  /// \see QuotedStringWriter
deba@1333
    92
  /// \see IdMap
deba@1333
    93
  /// \see DescriptorMap
deba@1394
    94
  /// \see \ref GraphWriter
alpar@1138
    95
  /// \see \ref graph-io-page
deba@1333
    96
  /// \author Balazs Dezso
deba@1137
    97
  template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
deba@1137
    98
  class GraphWriter {
deba@1137
    99
  public:
deba@1137
   100
    
deba@1137
   101
    typedef _Graph Graph;
deba@1137
   102
    typedef typename Graph::Node Node;
deba@1137
   103
    typedef typename Graph::Edge Edge;
deba@1137
   104
deba@1137
   105
    typedef _WriterTraits WriterTraits;
deba@1409
   106
deba@1137
   107
    /// \brief Construct a new GraphWriter.
deba@1137
   108
    ///
deba@1409
   109
    /// Construct a new GraphWriter. It writes the given graph
deba@1409
   110
    /// to the given stream.
deba@1208
   111
    GraphWriter(std::ostream& _os, const Graph& _graph) 
deba@1409
   112
      : writer(new LemonWriter(_os)), own_writer(true), 
deba@1409
   113
	graph(_graph), 
deba@1409
   114
	nodeset_writer(*writer, graph, std::string()),
deba@1409
   115
	edgeset_writer(*writer, graph, nodeset_writer, std::string()),
deba@1409
   116
	node_writer(*writer, nodeset_writer, std::string()),
deba@1409
   117
	edge_writer(*writer, edgeset_writer, std::string()),
deba@1409
   118
	attribute_writer(*writer, std::string()) {}
deba@1137
   119
deba@1409
   120
    /// \brief Construct a new GraphWriter.
deba@1409
   121
    ///
deba@1409
   122
    /// Construct a new GraphWriter. It writes into the given graph
deba@1409
   123
    /// to the given file.
deba@1409
   124
    GraphWriter(const std::string& _filename, const Graph& _graph) 
deba@1409
   125
      : writer(new LemonWriter(_filename)), own_writer(true), 
deba@1409
   126
	graph(_graph),
deba@1410
   127
	nodeset_writer(*writer, graph, std::string()),
deba@1410
   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
    ///
deba@1409
   135
    /// Construct a new GraphWriter. It writes into the given graph
deba@1409
   136
    /// to given LemonReader.
deba@1409
   137
    GraphWriter(LemonWriter& _writer, const Graph& _graph)
deba@1409
   138
      : writer(_writer), own_writer(false), 
deba@1409
   139
	graph(_graph),
deba@1409
   140
	nodeset_writer(*writer, graph, std::string()),
deba@1409
   141
	edgeset_writer(*writer, graph, nodeset_writer, std::string()),
deba@1409
   142
	node_writer(*writer, nodeset_writer, std::string()),
deba@1409
   143
	edge_writer(*writer, edgeset_writer, std::string()),
deba@1409
   144
	attribute_writer(*writer, std::string()) {}
deba@1137
   145
deba@1137
   146
    /// \brief Destruct the graph writer.
deba@1137
   147
    ///
deba@1137
   148
    /// Destruct the graph writer.
deba@1137
   149
    ~GraphWriter() {
deba@1409
   150
      if (own_writer) 
deba@1409
   151
	delete writer;
deba@1137
   152
    }
deba@1137
   153
deba@1137
   154
    /// \brief Add a new node map writer command for the writer.
deba@1137
   155
    ///
deba@1137
   156
    /// Add a new node map writer command for the writer.
deba@1137
   157
    template <typename Map>
deba@1394
   158
    GraphWriter& writeNodeMap(std::string name, const Map& map) {
deba@1409
   159
      nodeset_writer.writeMap(name, map);
deba@1409
   160
      return *this;
deba@1137
   161
    }
deba@1137
   162
deba@1137
   163
    /// \brief Add a new node map writer command for the writer.
deba@1137
   164
    ///
deba@1137
   165
    /// Add a new node map writer command for the writer.
deba@1137
   166
    template <typename Writer, typename Map>
deba@1394
   167
    GraphWriter& writeNodeMap(std::string name, const Map& map, 
deba@1409
   168
			     const Writer& writer = Writer()) {
deba@1409
   169
      nodeset_writer.writeMap(name, map, writer);
deba@1137
   170
      return *this;
deba@1137
   171
    }
deba@1137
   172
deba@1137
   173
deba@1137
   174
    /// \brief Add a new edge map writer command for the writer.
deba@1137
   175
    ///
deba@1137
   176
    /// Add a new edge map writer command for the writer.
deba@1137
   177
    template <typename Map>
deba@1394
   178
    GraphWriter& writeEdgeMap(std::string name, const Map& map) { 
deba@1409
   179
      edgeset_writer.writeMap(name, map);
deba@1409
   180
      return *this;
deba@1137
   181
    }
deba@1137
   182
deba@1137
   183
deba@1137
   184
    /// \brief Add a new edge map writer command for the writer.
deba@1137
   185
    ///
deba@1137
   186
    /// Add a new edge map writer command for the writer.
deba@1137
   187
    template <typename Writer, typename Map>
deba@1409
   188
    GraphWriter& writeEdgeMap(std::string name, const Map& map,
deba@1409
   189
			     const Writer& writer = Writer()) {
deba@1409
   190
      edgeset_writer.writeMap(name, map, writer);
deba@1137
   191
      return *this;
deba@1137
   192
    }
deba@1137
   193
deba@1137
   194
    /// \brief Add a new labeled node writer for the writer.
deba@1137
   195
    ///
deba@1137
   196
    /// Add a new labeled node writer for 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
deba@1137
   202
    /// \brief Add a new labeled edge writer for the writer.
deba@1137
   203
    ///
deba@1137
   204
    /// Add a new labeled edge writer for the writer.
deba@1394
   205
    GraphWriter& writeEdge(std::string name, const Edge& edge) {
deba@1409
   206
      edge_writer.writeEdge(name, edge);
deba@1409
   207
    }
deba@1409
   208
deba@1409
   209
    /// \brief Add a new attribute writer command.
deba@1409
   210
    ///
deba@1409
   211
    ///  Add a new attribute writer command.
deba@1409
   212
    template <typename Value>
deba@1409
   213
    GraphWriter& writeAttribute(std::string name, const Value& value) {
deba@1409
   214
      attribute_writer.writeAttribute(name, value);
deba@1409
   215
      return *this;
deba@1409
   216
    }
deba@1409
   217
    
deba@1409
   218
    /// \brief Add a new attribute writer command.
deba@1409
   219
    ///
deba@1409
   220
    ///  Add a new attribute writer command.
deba@1409
   221
    template <typename Writer, typename Value>
deba@1409
   222
    GraphWriter& writeAttribute(std::string name, const Value& value, 
deba@1409
   223
			       const Writer& writer) {
deba@1409
   224
      attribute_writer.writeAttribute<Writer>(name, value, writer);
deba@1137
   225
      return *this;
deba@1137
   226
    }
deba@1137
   227
deba@1409
   228
    /// \brief Conversion operator to LemonWriter.
deba@1409
   229
    ///
deba@1409
   230
    /// Conversion operator to LemonWriter. It make possible
deba@1409
   231
    /// to access the encapsulated \e LemonWriter, this way
deba@1409
   232
    /// you can attach to this writer new instances of 
deba@1409
   233
    /// \e LemonWriter::SectionWriter.
deba@1409
   234
    operator LemonWriter&() {
deba@1409
   235
      return *writer;
deba@1396
   236
    }
deba@1396
   237
deba@1137
   238
    /// \brief Executes the writer commands.
deba@1137
   239
    ///
deba@1137
   240
    /// Executes the writer commands.
deba@1409
   241
    void run() {
deba@1409
   242
      writer->run();
deba@1137
   243
    }
deba@1137
   244
deba@1137
   245
  private:
deba@1137
   246
deba@1409
   247
    LemonWriter* writer;
deba@1409
   248
    bool own_writer;
deba@1137
   249
deba@1208
   250
    const Graph& graph;
deba@1137
   251
deba@1409
   252
    NodeSetWriter<Graph, WriterTraits> nodeset_writer;
deba@1409
   253
    EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
deba@1409
   254
deba@1409
   255
    NodeWriter<Graph> node_writer;
deba@1409
   256
    EdgeWriter<Graph> edge_writer;
deba@1409
   257
    
deba@1409
   258
    AttributeWriter<WriterTraits> attribute_writer;
deba@1137
   259
  };
deba@1137
   260
deba@1409
   261
deba@1333
   262
  /// \brief Write a graph to the output.
deba@1333
   263
  ///
deba@1333
   264
  /// Write a graph to the output.
deba@1333
   265
  /// \param os The output stream.
deba@1333
   266
  /// \param g The graph.
deba@1333
   267
  /// \param capacity The capacity map.
deba@1333
   268
  /// \param s The source node.
deba@1333
   269
  /// \param t The target node.
deba@1333
   270
  /// \param cost The cost map.
deba@1208
   271
  template<typename Graph, typename CapacityMap, typename CostMap>
deba@1208
   272
  void writeGraph(std::ostream& os, const Graph &g, 
deba@1208
   273
		  const CapacityMap& capacity, const typename Graph::Node &s,
deba@1208
   274
		  const typename Graph::Node &t, const CostMap& cost) {
deba@1394
   275
    GraphWriter<Graph> writer(os, g);
deba@1208
   276
    IdMap<Graph, typename Graph::Node> nodeIdMap(g);
deba@1394
   277
    writer.writeNodeMap("id", nodeIdMap);
deba@1208
   278
    IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
deba@1394
   279
    writer.writeEdgeMap("id", edgeIdMap);
deba@1394
   280
    writer.writeEdgeMap("capacity", capacity);
deba@1394
   281
    writer.writeEdgeMap("cost", cost);
deba@1394
   282
    writer.writeNode("source", s);
deba@1394
   283
    writer.writeNode("target", t);
deba@1394
   284
    writer.run();
deba@1208
   285
  }
deba@1208
   286
deba@1333
   287
  /// \brief Write a graph to the output.
deba@1333
   288
  ///
deba@1333
   289
  /// Write a graph to the output.
deba@1333
   290
  /// \param os The output stream.
deba@1333
   291
  /// \param g The graph.
deba@1333
   292
  /// \param capacity The capacity map.
deba@1333
   293
  /// \param s The source node.
deba@1333
   294
  /// \param t The target node.
deba@1297
   295
  template<typename Graph, typename CapacityMap>
deba@1208
   296
  void writeGraph(std::ostream& os, const Graph &g, 
deba@1208
   297
		  const CapacityMap& capacity, const typename Graph::Node &s,
deba@1208
   298
		  const typename Graph::Node &t) {
deba@1394
   299
    GraphWriter<Graph> writer(os, g);
deba@1208
   300
    IdMap<Graph, typename Graph::Node> nodeIdMap(g);
deba@1394
   301
    writer.writeNodeMap("id", nodeIdMap);
deba@1208
   302
    IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
deba@1394
   303
    writer.writeEdgeMap("id", edgeIdMap);
deba@1394
   304
    writer.writeEdgeMap("capacity", capacity);
deba@1394
   305
    writer.writeNode("source", s);
deba@1394
   306
    writer.writeNode("target", t);
deba@1394
   307
    writer.run();
deba@1208
   308
  }
deba@1208
   309
deba@1333
   310
  /// \brief Write a graph to the output.
deba@1333
   311
  ///
deba@1333
   312
  /// Write a graph to the output.
deba@1333
   313
  /// \param os The output stream.
deba@1333
   314
  /// \param g The graph.
deba@1333
   315
  /// \param capacity The capacity map.
deba@1333
   316
  /// \param s The source node.
deba@1208
   317
  template<typename Graph, typename CapacityMap>
deba@1208
   318
  void writeGraph(std::ostream& os, const Graph &g, 
deba@1208
   319
		  const CapacityMap& capacity, const typename Graph::Node &s) {
deba@1394
   320
    GraphWriter<Graph> writer(os, g);
deba@1208
   321
    IdMap<Graph, typename Graph::Node> nodeIdMap(g);
deba@1394
   322
    writer.writeNodeMap("id", nodeIdMap);
deba@1208
   323
    IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
deba@1394
   324
    writer.writeEdgeMap("id", edgeIdMap);
deba@1394
   325
    writer.writeEdgeMap("capacity", capacity);
deba@1394
   326
    writer.writeNode("source", s);
deba@1394
   327
    writer.run();
deba@1208
   328
  }
deba@1333
   329
deba@1333
   330
  /// \brief Write a graph to the output.
deba@1333
   331
  ///
deba@1333
   332
  /// Write a graph to the output.
deba@1333
   333
  /// \param os The output stream.
deba@1333
   334
  /// \param g The graph.
deba@1333
   335
  /// \param capacity The capacity map.
deba@1208
   336
  template<typename Graph, typename CapacityMap>
deba@1208
   337
  void writeGraph(std::ostream& os, const Graph &g, 
deba@1208
   338
		  const CapacityMap& capacity) {
deba@1394
   339
    GraphWriter<Graph> writer(os, g);
deba@1208
   340
    IdMap<Graph, typename Graph::Node> nodeIdMap(g);
deba@1394
   341
    writer.writeNodeMap("id", nodeIdMap);
deba@1208
   342
    IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
deba@1394
   343
    writer.writeEdgeMap("id", edgeIdMap);
deba@1394
   344
    writer.writeEdgeMap("capacity", capacity);
deba@1394
   345
    writer.run();
deba@1208
   346
  }
deba@1333
   347
deba@1333
   348
  /// \brief Write a graph to the output.
deba@1333
   349
  ///
deba@1333
   350
  /// Write a graph to the output.
deba@1333
   351
  /// \param os The output stream.
deba@1333
   352
  /// \param g The graph.
deba@1208
   353
  template<typename Graph>
deba@1208
   354
  void writeGraph(std::ostream& os, const Graph &g) {
deba@1394
   355
    GraphWriter<Graph> writer(os, g);
deba@1208
   356
    IdMap<Graph, typename Graph::Node> nodeIdMap(g);
deba@1394
   357
    writer.writeNodeMap("id", nodeIdMap);
deba@1208
   358
    IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
deba@1394
   359
    writer.writeEdgeMap("id", edgeIdMap);
deba@1394
   360
    writer.run();
deba@1208
   361
  }
deba@1208
   362
deba@1333
   363
  /// @}
deba@1137
   364
deba@1137
   365
}
deba@1214
   366
deba@1214
   367
#endif