lemon/graph_writer.h
author deba
Sun, 30 Dec 2007 18:23:32 +0000
changeset 2550 f26368148b9c
parent 2467 2025a571895e
child 2553 bfced05fa852
permissions -rw-r--r--
Changing degree of tournament tree
Bug fix in union find
Small efficiency improvment in bipartite matchings
deba@1137
     1
/* -*- C++ -*-
deba@1137
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@2391
     5
 * Copyright (C) 2003-2007
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1137
     8
 *
deba@1137
     9
 * Permission to use, modify and distribute this software is granted
deba@1137
    10
 * provided that this copyright notice appears in all copies. For
deba@1137
    11
 * precise terms see the accompanying LICENSE file.
deba@1137
    12
 *
deba@1137
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@1137
    14
 * express or implied, and with no claim as to its suitability for any
deba@1137
    15
 * purpose.
deba@1137
    16
 *
deba@1137
    17
 */
deba@1137
    18
deba@2083
    19
///\ingroup lemon_io
deba@1137
    20
///\file
alpar@1287
    21
///\brief Lemon Graph Format writer.
athos@1534
    22
///
deba@1137
    23
deba@1214
    24
#ifndef LEMON_GRAPH_WRITER_H
deba@1214
    25
#define LEMON_GRAPH_WRITER_H
deba@1137
    26
deba@1137
    27
#include <iostream>
deba@1137
    28
deba@1137
    29
#include <lemon/error.h>
deba@1409
    30
#include <lemon/lemon_writer.h>
deba@1137
    31
deba@1137
    32
namespace lemon {
deba@1137
    33
deba@2083
    34
  /// \addtogroup lemon_io
deba@1333
    35
  /// @{
deba@1333
    36
deba@1137
    37
  /// \brief The graph writer class.
deba@1137
    38
  ///
deba@2200
    39
  /// The \c GraphWriter class provides the graph output.  Before you
deba@2200
    40
  /// read this documentation it might be useful to read the general
deba@2200
    41
  /// description of \ref graph-io-page "Graph Input-Output".
athos@1540
    42
  ///
deba@2200
    43
  /// To write a graph you should first give writing commands to the
deba@2200
    44
  /// writer. You can declare write commands as \c NodeMap or \c
deba@2200
    45
  /// EdgeMap writing and labeled Node and Edge writing.
deba@1333
    46
  ///
alpar@1946
    47
  ///\code
deba@1333
    48
  /// GraphWriter<ListGraph> writer(std::cout, graph);
alpar@1946
    49
  ///\endcode
deba@1333
    50
  ///
deba@2200
    51
  /// The \c writeNodeMap() function declares a \c NodeMap writing
deba@2200
    52
  /// command in the \c GraphWriter. You should give as parameter the
deba@2200
    53
  /// name of the map and the map object. The NodeMap writing command
deba@2200
    54
  /// with name "label" should write a unique map because it is
deba@2200
    55
  /// regarded as label map (such a map is essential if the graph has
deba@2200
    56
  /// edges).
deba@1333
    57
  ///
alpar@1946
    58
  ///\code
deba@1901
    59
  /// IdMap<ListGraph, Node> nodeLabelMap;
deba@1901
    60
  /// writer.writeNodeMap("label", nodeLabelMap);
deba@1333
    61
  ///
deba@1421
    62
  /// writer.writeNodeMap("coords", coords);
deba@1394
    63
  /// writer.writeNodeMap("color", colorMap);
alpar@1946
    64
  ///\endcode
deba@1333
    65
  ///
deba@1394
    66
  /// With the \c writeEdgeMap() member function you can give an edge map
deba@1333
    67
  /// writing command similar to the NodeMaps.
deba@1333
    68
  ///
alpar@1946
    69
  ///\code
deba@1333
    70
  /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
deba@1333
    71
  ///   edgeDescMap(graph);
deba@1394
    72
  /// writer.writeEdgeMap("descriptor", edgeDescMap);
deba@1333
    73
  ///
deba@1394
    74
  /// writer.writeEdgeMap("weight", weightMap);
deba@1394
    75
  /// writer.writeEdgeMap("label", labelMap);
alpar@1946
    76
  ///\endcode
deba@1333
    77
  ///
deba@1394
    78
  /// With \c writeNode() and \c writeEdge() functions you can 
athos@1526
    79
  /// point out Nodes and Edges in the graph. For example, you can 
athos@1526
    80
  /// write out the source and target of a maximum flow instance.
deba@1333
    81
  ///
alpar@1946
    82
  ///\code
deba@1394
    83
  /// writer.writeNode("source", sourceNode);
deba@1394
    84
  /// writer.writeNode("target", targetNode);
deba@1333
    85
  ///
deba@1394
    86
  /// writer.writeEdge("observed", edge);
alpar@1946
    87
  ///\endcode
deba@1333
    88
  ///
deba@1333
    89
  /// After you give all write commands you must call the \c run() member
athos@1526
    90
  /// function, which executes all the writing commands.
deba@1333
    91
  ///
alpar@1946
    92
  ///\code
deba@1333
    93
  /// writer.run();
alpar@1946
    94
  ///\endcode
deba@1333
    95
  ///
alpar@1287
    96
  /// \see DefaultWriterTraits
alpar@1287
    97
  /// \see QuotedStringWriter
deba@1333
    98
  /// \see IdMap
deba@1333
    99
  /// \see DescriptorMap
deba@1421
   100
  /// \see \ref GraphReader
alpar@1138
   101
  /// \see \ref graph-io-page
deba@1333
   102
  /// \author Balazs Dezso
deba@1137
   103
  template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
deba@1137
   104
  class GraphWriter {
deba@1137
   105
  public:
deba@1137
   106
    
deba@1137
   107
    typedef _Graph Graph;
deba@1137
   108
    typedef typename Graph::Node Node;
deba@1137
   109
    typedef typename Graph::Edge Edge;
deba@1137
   110
deba@1137
   111
    typedef _WriterTraits WriterTraits;
deba@1409
   112
deba@1137
   113
    /// \brief Construct a new GraphWriter.
deba@1137
   114
    ///
athos@1526
   115
    /// This function constructs a new GraphWriter to write the given graph
deba@1409
   116
    /// to the given stream.
deba@1208
   117
    GraphWriter(std::ostream& _os, const Graph& _graph) 
deba@1409
   118
      : writer(new LemonWriter(_os)), own_writer(true), 
deba@1421
   119
	nodeset_writer(*writer, _graph, std::string()),
deba@1421
   120
	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
deba@1409
   121
	node_writer(*writer, nodeset_writer, std::string()),
deba@1409
   122
	edge_writer(*writer, edgeset_writer, std::string()),
deba@1409
   123
	attribute_writer(*writer, std::string()) {}
deba@1137
   124
deba@1409
   125
    /// \brief Construct a new GraphWriter.
deba@1409
   126
    ///
athos@1526
   127
    /// This function constructs a new GraphWriter to write the given graph
deba@1409
   128
    /// to the given file.
deba@1409
   129
    GraphWriter(const std::string& _filename, const Graph& _graph) 
deba@1409
   130
      : writer(new LemonWriter(_filename)), own_writer(true), 
deba@1421
   131
	nodeset_writer(*writer, _graph, std::string()),
deba@1421
   132
	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
deba@1409
   133
	node_writer(*writer, nodeset_writer, std::string()),
deba@1409
   134
	edge_writer(*writer, edgeset_writer, std::string()),
deba@1409
   135
	attribute_writer(*writer, std::string()) {}
deba@1409
   136
deba@1409
   137
    /// \brief Construct a new GraphWriter.
deba@1409
   138
    ///
athos@1526
   139
    /// This function constructs a new GraphWriter to write the given graph
athos@1526
   140
    /// to the given LemonReader.
deba@1409
   141
    GraphWriter(LemonWriter& _writer, const Graph& _graph)
deba@1409
   142
      : writer(_writer), own_writer(false), 
deba@1421
   143
	nodeset_writer(*writer, _graph, std::string()),
deba@1421
   144
	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
deba@1409
   145
	node_writer(*writer, nodeset_writer, std::string()),
deba@1409
   146
	edge_writer(*writer, edgeset_writer, std::string()),
deba@1409
   147
	attribute_writer(*writer, std::string()) {}
deba@1137
   148
deba@1137
   149
    /// \brief Destruct the graph writer.
deba@1137
   150
    ///
athos@1526
   151
    /// This function destructs the graph writer.
deba@1137
   152
    ~GraphWriter() {
deba@1409
   153
      if (own_writer) 
deba@1409
   154
	delete writer;
deba@1137
   155
    }
deba@1137
   156
athos@1526
   157
    /// \brief Issue a new node map writing command for the writer.
deba@1137
   158
    ///
deba@2502
   159
    /// This function issues a new <i> node map writing command</i> to the writer.
deba@1137
   160
    template <typename Map>
deba@2386
   161
    GraphWriter& writeNodeMap(std::string label, const Map& map) {
deba@2386
   162
      nodeset_writer.writeNodeMap(label, map);
deba@1409
   163
      return *this;
deba@1137
   164
    }
deba@1137
   165
athos@1540
   166
athos@1526
   167
    /// \brief Issue a new node map writing command for the writer.
deba@1137
   168
    ///
deba@2502
   169
    /// This function issues a new <i> node map writing command</i> to the writer.
deba@2386
   170
    template <typename ItemWriter, typename Map>
deba@2386
   171
    GraphWriter& writeNodeMap(std::string label, const Map& map, 
deba@2386
   172
			      const ItemWriter& iw = ItemWriter()) {
deba@2386
   173
      nodeset_writer.writeNodeMap(label, map, iw);
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@2386
   182
    GraphWriter& writeEdgeMap(std::string label, const Map& map) { 
deba@2386
   183
      edgeset_writer.writeEdgeMap(label, 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@2386
   191
    template <typename ItemWriter, typename Map>
deba@2386
   192
    GraphWriter& writeEdgeMap(std::string label, const Map& map,
deba@2386
   193
			      const ItemWriter& iw = ItemWriter()) {
deba@2386
   194
      edgeset_writer.writeEdgeMap(label, map, iw);
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@2386
   202
    GraphWriter& writeNode(std::string label, const Node& node) {
deba@2386
   203
      node_writer.writeNode(label, 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@2386
   211
    GraphWriter& writeEdge(std::string label, const Edge& edge) {
deba@2386
   212
      edge_writer.writeEdge(label, 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@2386
   220
    GraphWriter& writeAttribute(std::string label, const Value& value) {
deba@2386
   221
      attribute_writer.writeAttribute(label, 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@2386
   229
    template <typename ItemWriter, typename Value>
deba@2386
   230
    GraphWriter& writeAttribute(std::string label, const Value& value, 
deba@2386
   231
			       const ItemWriter& iw = ItemWriter()) {
deba@2386
   232
      attribute_writer.writeAttribute(label, value, iw);
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 
athos@1540
   241
    /// \e LemonWriter::SectionWriter. For more details see
athos@1540
   242
    /// the \ref rwbackground "Background of Reading and Writing".
deba@1409
   243
    operator LemonWriter&() {
deba@1409
   244
      return *writer;
deba@1396
   245
    }
deba@1396
   246
athos@1526
   247
    /// \brief Executes the writing commands.
deba@1137
   248
    ///
athos@1526
   249
    /// Executes the writing commands.
deba@1409
   250
    void run() {
deba@1409
   251
      writer->run();
deba@1137
   252
    }
deba@1137
   253
deba@2467
   254
    /// \brief Returns true if the writer can give back the labels by the items.
deba@2467
   255
    ///
deba@2467
   256
    /// Returns true if the writer can give back the the labels by the items.
deba@2467
   257
    bool isLabelWriter() const {
deba@2467
   258
      return nodeset_writer.isLabelWriter() && 
deba@2467
   259
        edgeset_writer.isLabelWriter();
deba@2467
   260
    }
deba@2467
   261
deba@1901
   262
    /// \brief Write the label of the given node.
deba@1429
   263
    ///
deba@2467
   264
    /// It writes the label of the given node. If there was written a "label"
athos@1526
   265
    /// named node map then it will write the map value belonging to the node.
deba@1901
   266
    void writeLabel(std::ostream& os, const Node& item) const {
deba@1901
   267
      nodeset_writer.writeLabel(os, item);
deba@1429
   268
    } 
deba@1429
   269
deba@1901
   270
    /// \brief Write the label of the given edge.
deba@1429
   271
    ///
deba@2467
   272
    /// It writes the label of the given edge. If there was written a "label"
athos@1526
   273
    /// named edge map then it will write the map value belonging to the edge.
deba@1901
   274
    void writeLabel(std::ostream& os, const Edge& item) const {
deba@1901
   275
      edgeset_writer.writeLabel(os, item);
deba@1429
   276
    } 
deba@1429
   277
deba@2467
   278
    /// \brief Sorts the given node vector by label.
deba@2467
   279
    ///
deba@2467
   280
    /// Sorts the given node vector by label. If there was written an
deba@2467
   281
    /// "label" named map then the vector will be sorted by the values
deba@2467
   282
    /// of this map. Otherwise if the \c forceLabel parameter was true
deba@2467
   283
    /// it will be sorted by its id in the graph.
deba@2467
   284
    void sortByLabel(std::vector<Node>& nodes) const {
deba@2467
   285
      nodeset_writer.sortByLabel(nodes);
deba@2467
   286
    }
deba@2467
   287
deba@2467
   288
    /// \brief Sorts the given edge vector by label.
deba@2467
   289
    ///
deba@2467
   290
    /// Sorts the given edge vector by label. If there was written an
deba@2467
   291
    /// "label" named map then the vector will be sorted by the values
deba@2467
   292
    /// of this map. Otherwise if the \c forceLabel parameter was true
deba@2467
   293
    /// it will be sorted by its id in the graph.
deba@2467
   294
    void sortByLabel(std::vector<Edge>& edges) const {
deba@2467
   295
      edgeset_writer.sortByLabel(edges);
deba@2467
   296
    }
deba@2467
   297
deba@1137
   298
  private:
deba@1137
   299
deba@1409
   300
    LemonWriter* writer;
deba@1409
   301
    bool own_writer;
deba@1137
   302
deba@1409
   303
    NodeSetWriter<Graph, WriterTraits> nodeset_writer;
deba@1409
   304
    EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
deba@1409
   305
deba@1409
   306
    NodeWriter<Graph> node_writer;
deba@1409
   307
    EdgeWriter<Graph> edge_writer;
deba@1409
   308
    
deba@1409
   309
    AttributeWriter<WriterTraits> attribute_writer;
deba@1137
   310
  };
deba@1137
   311
deba@1409
   312
deba@1421
   313
  /// \brief The undirected graph writer class.
deba@1421
   314
  ///
klao@1909
   315
  /// The \c UGraphWriter class provides the ugraph output. To write 
athos@1526
   316
  /// a graph you should first give writing commands to the writer. You can 
klao@1909
   317
  /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap 
klao@1909
   318
  /// writing and labeled Node, Edge or UEdge writing.
deba@1421
   319
  ///
alpar@1946
   320
  ///\code
klao@1909
   321
  /// UGraphWriter<ListUGraph> writer(std::cout, graph);
alpar@1946
   322
  ///\endcode
deba@1421
   323
  ///
deba@1421
   324
  /// The \c writeNodeMap() function declares a \c NodeMap writing 
klao@1909
   325
  /// command in the \c UGraphWriter. You should give as parameter 
deba@1421
   326
  /// the name of the map and the map object. The NodeMap writing 
deba@1901
   327
  /// command with name "label" should write a unique map because it 
deba@1901
   328
  /// is regarded as label map.
deba@1421
   329
  ///
alpar@1946
   330
  ///\code
klao@1909
   331
  /// IdMap<ListUGraph, Node> nodeLabelMap;
deba@1901
   332
  /// writer.writeNodeMap("label", nodeLabelMap);
deba@1421
   333
  ///
deba@1421
   334
  /// writer.writeNodeMap("coords", coords);
deba@1421
   335
  /// writer.writeNodeMap("color", colorMap);
alpar@1946
   336
  ///\endcode
deba@1421
   337
  ///
klao@1909
   338
  /// With the \c writeUEdgeMap() member function you can give an 
deba@1421
   339
  /// undirected edge map writing command similar to the NodeMaps.
deba@1421
   340
  ///
alpar@1946
   341
  ///\code
deba@1421
   342
  /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
deba@1421
   343
  ///   edgeDescMap(graph);
klao@1909
   344
  /// writer.writeUEdgeMap("descriptor", edgeDescMap);
deba@1421
   345
  ///
klao@1909
   346
  /// writer.writeUEdgeMap("weight", weightMap);
klao@1909
   347
  /// writer.writeUEdgeMap("label", labelMap);
alpar@1946
   348
  ///\endcode
deba@1421
   349
  /// 
deba@1421
   350
  /// The EdgeMap handling is just a syntactical sugar. It writes
deba@1421
   351
  /// two undirected edge map with '+' and '-' prefix in the name.
deba@1421
   352
  ///
alpar@1946
   353
  ///\code
deba@1421
   354
  /// writer.writeEdgeMap("capacity", capacityMap);
alpar@1946
   355
  ///\endcode
deba@1421
   356
  ///
deba@1421
   357
  ///
klao@1909
   358
  /// With \c writeNode() and \c writeUEdge() functions you can 
athos@1526
   359
  /// designate nodes and undirected edges in the graph. For example, you can 
deba@1421
   360
  /// write out the source and target of the graph.
deba@1421
   361
  ///
alpar@1946
   362
  ///\code
deba@1421
   363
  /// writer.writeNode("source", sourceNode);
deba@1421
   364
  /// writer.writeNode("target", targetNode);
deba@1421
   365
  ///
klao@1909
   366
  /// writer.writeUEdge("observed", uEdge);
alpar@1946
   367
  ///\endcode
deba@1421
   368
  ///
deba@1421
   369
  /// After you give all write commands you must call the \c run() member
athos@1526
   370
  /// function, which executes all the writing commands.
deba@1421
   371
  ///
alpar@1946
   372
  ///\code
deba@1421
   373
  /// writer.run();
alpar@1946
   374
  ///\endcode
deba@1421
   375
  ///
deba@1421
   376
  /// \see DefaultWriterTraits
deba@1421
   377
  /// \see QuotedStringWriter
deba@1421
   378
  /// \see IdMap
deba@1421
   379
  /// \see DescriptorMap
deba@1421
   380
  /// \see \ref GraphWriter
deba@1421
   381
  /// \see \ref graph-io-page
deba@1421
   382
  /// \author Balazs Dezso
deba@1421
   383
  template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
klao@1909
   384
  class UGraphWriter {
deba@1421
   385
  public:
deba@1421
   386
    
deba@1421
   387
    typedef _Graph Graph;
deba@1421
   388
    typedef typename Graph::Node Node;
deba@1421
   389
    typedef typename Graph::Edge Edge;
klao@1909
   390
    typedef typename Graph::UEdge UEdge;
deba@1421
   391
deba@1421
   392
    typedef _WriterTraits WriterTraits;
deba@1421
   393
klao@1909
   394
    /// \brief Construct a new UGraphWriter.
deba@1421
   395
    ///
klao@1909
   396
    /// Construct a new UGraphWriter. It writes the given graph
deba@1421
   397
    /// to the given stream.
klao@1909
   398
    UGraphWriter(std::ostream& _os, const Graph& _graph) 
deba@1421
   399
      : writer(new LemonWriter(_os)), own_writer(true), 
deba@1421
   400
	nodeset_writer(*writer, _graph, std::string()),
deba@2467
   401
	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
deba@1421
   402
	node_writer(*writer, nodeset_writer, std::string()),
deba@2467
   403
	uedge_writer(*writer, uedgeset_writer, std::string()),
deba@1421
   404
	attribute_writer(*writer, std::string()) {}
deba@1421
   405
klao@1909
   406
    /// \brief Construct a new UGraphWriter.
deba@1421
   407
    ///
klao@1909
   408
    /// Construct a new UGraphWriter. It writes the given graph
deba@1421
   409
    /// to the given file.
klao@1909
   410
    UGraphWriter(const std::string& _filename, const Graph& _graph) 
deba@1421
   411
      : writer(new LemonWriter(_filename)), own_writer(true), 
deba@1421
   412
	nodeset_writer(*writer, _graph, std::string()),
deba@2467
   413
	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
deba@1421
   414
	node_writer(*writer, nodeset_writer, std::string()),
deba@2467
   415
	uedge_writer(*writer, uedgeset_writer, std::string()),
deba@1421
   416
	attribute_writer(*writer, std::string()) {}
deba@1421
   417
klao@1909
   418
    /// \brief Construct a new UGraphWriter.
deba@1421
   419
    ///
klao@1909
   420
    /// Construct a new UGraphWriter. It writes the given graph
deba@2467
   421
    /// to given LemonWriter.
klao@1909
   422
    UGraphWriter(LemonWriter& _writer, const Graph& _graph)
deba@1421
   423
      : writer(_writer), own_writer(false), 
deba@1421
   424
	nodeset_writer(*writer, _graph, std::string()),
deba@2467
   425
	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
deba@1421
   426
	node_writer(*writer, nodeset_writer, std::string()),
deba@2467
   427
	uedge_writer(*writer, uedgeset_writer, std::string()),
deba@1421
   428
	attribute_writer(*writer, std::string()) {}
deba@1421
   429
deba@1421
   430
    /// \brief Destruct the graph writer.
deba@1421
   431
    ///
deba@1421
   432
    /// Destruct the graph writer.
klao@1909
   433
    ~UGraphWriter() {
deba@1421
   434
      if (own_writer) 
deba@1421
   435
	delete writer;
deba@1421
   436
    }
deba@1421
   437
athos@1526
   438
    /// \brief Issue a new node map writing command to the writer.
deba@1421
   439
    ///
deba@2200
   440
    /// This function issues a new <i> node map writing command</i> to
deba@2200
   441
    /// the writer.
deba@1421
   442
    template <typename Map>
deba@2386
   443
    UGraphWriter& writeNodeMap(std::string label, const Map& map) {
deba@2386
   444
      nodeset_writer.writeNodeMap(label, map);
deba@1421
   445
      return *this;
deba@1421
   446
    }
deba@1421
   447
athos@1526
   448
    /// \brief Issue a new node map writing command to the writer.
deba@1421
   449
    ///
deba@2200
   450
    /// This function issues a new <i> node map writing command</i> to
deba@2200
   451
    /// the writer.
deba@2386
   452
    template <typename ItemWriter, typename Map>
deba@2386
   453
    UGraphWriter& writeNodeMap(std::string label, const Map& map, 
deba@2386
   454
			      const ItemWriter& iw = ItemWriter()) {
deba@2386
   455
      nodeset_writer.writeNodeMap(label, map, iw);
deba@1421
   456
      return *this;
deba@1421
   457
    }
deba@1421
   458
athos@1526
   459
    /// \brief Issue a new edge map writing command to the writer.
deba@1421
   460
    ///
deba@2200
   461
    /// This function issues a new <i> edge map writing command</i> to
deba@2200
   462
    /// the writer.
deba@1421
   463
    template <typename Map>
deba@2386
   464
    UGraphWriter& writeEdgeMap(std::string label, const Map& map) { 
deba@2467
   465
      uedgeset_writer.writeEdgeMap(label, map);
deba@1421
   466
      return *this;
deba@1421
   467
    }
deba@1421
   468
athos@1526
   469
    /// \brief Issue a new edge map writing command to the writer.
deba@1421
   470
    ///
deba@2200
   471
    /// This function issues a new <i> edge map writing command</i> to
deba@2200
   472
    /// the writer.
deba@2386
   473
    template <typename ItemWriter, typename Map>
deba@2386
   474
    UGraphWriter& writeEdgeMap(std::string label, const Map& map,
deba@2386
   475
				   const ItemWriter& iw = ItemWriter()) {
deba@2467
   476
      uedgeset_writer.writeEdgeMap(label, map, iw);
deba@1421
   477
      return *this;
deba@1421
   478
    }
deba@1421
   479
athos@1526
   480
    /// \brief Issue a new undirected edge map writing command to the writer.
deba@1421
   481
    ///
athos@1526
   482
    /// This function issues a new <i> undirected edge map writing
athos@1526
   483
    /// command</i> to the writer.
deba@1421
   484
    template <typename Map>
deba@2386
   485
    UGraphWriter& writeUEdgeMap(std::string label, const Map& map) { 
deba@2467
   486
      uedgeset_writer.writeUEdgeMap(label, map);
deba@1421
   487
      return *this;
deba@1421
   488
    }
deba@1421
   489
athos@1526
   490
    /// \brief Issue a new undirected edge map writing command to the writer.
deba@1421
   491
    ///
athos@1526
   492
    /// This function issues a new <i> undirected edge map writing
athos@1526
   493
    /// command</i> to the writer.
deba@2386
   494
   template <typename ItemWriter, typename Map>
deba@2386
   495
    UGraphWriter& writeUEdgeMap(std::string label, const Map& map,
deba@2386
   496
					const ItemWriter& iw = ItemWriter()) {
deba@2467
   497
      uedgeset_writer.writeUEdgeMap(label, map, iw);
deba@1421
   498
      return *this;
deba@1421
   499
    }
deba@1421
   500
athos@1526
   501
    /// \brief Issue a new labeled node writer to the writer.
deba@1421
   502
    ///
athos@1526
   503
    /// This function issues a new <i> labeled node writing
athos@1526
   504
    /// command</i> to the writer.
deba@2386
   505
    UGraphWriter& writeNode(std::string label, const Node& node) {
deba@2386
   506
      node_writer.writeNode(label, node);
deba@1421
   507
      return *this;
deba@1421
   508
    }
deba@1421
   509
athos@1526
   510
    /// \brief Issue a new labeled edge writer to the writer.
deba@1421
   511
    ///
athos@1526
   512
    /// This function issues a new <i> labeled edge writing
athos@1526
   513
    /// command</i> to the writer.
deba@2386
   514
    UGraphWriter& writeEdge(std::string label, const Edge& edge) {
deba@2467
   515
      uedge_writer.writeEdge(label, edge);
deba@1429
   516
    }
deba@1429
   517
athos@1526
   518
    /// \brief Issue a new labeled undirected edge writing command to
athos@1526
   519
    /// the writer.
deba@1429
   520
    ///
athos@1526
   521
    /// Issue a new <i>labeled undirected edge writing command</i> to
athos@1526
   522
    /// the writer.
deba@2386
   523
    UGraphWriter& writeUEdge(std::string label, const UEdge& edge) {
deba@2467
   524
      uedge_writer.writeUEdge(label, edge);
deba@1421
   525
    }
deba@1421
   526
athos@1526
   527
    /// \brief Issue a new attribute writing command.
deba@1421
   528
    ///
athos@1526
   529
    /// This function issues a new <i> attribute writing
athos@1526
   530
    /// command</i> to the writer.
deba@1421
   531
    template <typename Value>
deba@2386
   532
    UGraphWriter& writeAttribute(std::string label, const Value& value) {
deba@2386
   533
      attribute_writer.writeAttribute(label, value);
deba@1421
   534
      return *this;
deba@1421
   535
    }
deba@1421
   536
    
athos@1526
   537
    /// \brief Issue a new attribute writing command.
deba@1421
   538
    ///
athos@1526
   539
    /// This function issues a new <i> attribute writing
athos@1526
   540
    /// command</i> to the writer.
deba@2386
   541
    template <typename ItemWriter, typename Value>
deba@2386
   542
    UGraphWriter& writeAttribute(std::string label, const Value& value, 
deba@2386
   543
			       const ItemWriter& iw = ItemWriter()) {
deba@2386
   544
      attribute_writer.writeAttribute(label, value, iw);
deba@1421
   545
      return *this;
deba@1421
   546
    }
deba@1421
   547
deba@1421
   548
    /// \brief Conversion operator to LemonWriter.
deba@1421
   549
    ///
athos@1526
   550
    /// Conversion operator to LemonWriter. It makes possible
deba@1421
   551
    /// to access the encapsulated \e LemonWriter, this way
deba@1421
   552
    /// you can attach to this writer new instances of 
deba@1421
   553
    /// \e LemonWriter::SectionWriter.
deba@1421
   554
    operator LemonWriter&() {
deba@1421
   555
      return *writer;
deba@1421
   556
    }
deba@1421
   557
athos@1526
   558
    /// \brief Executes the writing commands.
deba@1421
   559
    ///
athos@1526
   560
    /// Executes the writing commands.
deba@1421
   561
    void run() {
deba@1421
   562
      writer->run();
deba@1421
   563
    }
deba@1421
   564
deba@2467
   565
    /// \brief Returns true if the writer can give back the labels by the items.
deba@2467
   566
    ///
deba@2467
   567
    /// Returns true if the writer can give back the the labels by the items.
deba@2467
   568
    bool isLabelWriter() const {
deba@2467
   569
      return nodeset_writer.isLabelWriter() && 
deba@2467
   570
        uedgeset_writer.isLabelWriter();
deba@2467
   571
    }
deba@2467
   572
deba@1901
   573
    /// \brief Write the label of the given node.
deba@1429
   574
    ///
deba@2467
   575
    /// It writes the label of the given node. If there was written a "label"
athos@1526
   576
    /// named node map then it will write the map value belonging to the node.
deba@1901
   577
    void writeLabel(std::ostream& os, const Node& item) const {
deba@1901
   578
      nodeset_writer.writeLabel(os, item);
deba@1429
   579
    } 
deba@1429
   580
deba@1901
   581
    /// \brief Write the label of the given edge.
deba@1429
   582
    ///
deba@2467
   583
    /// It writes the label of the given edge. If there was written a "label"
athos@1526
   584
    /// named edge map then it will write the map value belonging to the edge.
deba@1901
   585
    void writeLabel(std::ostream& os, const Edge& item) const {
deba@2467
   586
      uedgeset_writer.writeLabel(os, item);
deba@1429
   587
    } 
deba@1429
   588
deba@1901
   589
    /// \brief Write the label of the given undirected edge.
deba@1429
   590
    ///
deba@2200
   591
    /// It writes the label of the given undirected edge. If there was
deba@2467
   592
    /// written a "label" named edge map then it will write the map
deba@2200
   593
    /// value belonging to the edge.
klao@1909
   594
    void writeLabel(std::ostream& os, const UEdge& item) const {
deba@2467
   595
      uedgeset_writer.writeLabel(os, item);
deba@1429
   596
    } 
deba@1429
   597
deba@2467
   598
    /// \brief Sorts the given node vector by label.
deba@2467
   599
    ///
deba@2467
   600
    /// Sorts the given node vector by label. If there was written an
deba@2467
   601
    /// "label" named map then the vector will be sorted by the values
deba@2467
   602
    /// of this map. Otherwise if the \c forceLabel parameter was true
deba@2467
   603
    /// it will be sorted by its id in the graph.
deba@2467
   604
    void sortByLabel(std::vector<Node>& nodes) const {
deba@2467
   605
      nodeset_writer.sortByLabel(nodes);
deba@2467
   606
    }
deba@2467
   607
deba@2467
   608
    /// \brief Sorts the given edge vector by label.
deba@2467
   609
    ///
deba@2467
   610
    /// Sorts the given edge vector by label. If there was written an
deba@2467
   611
    /// "label" named map then the vector will be sorted by the values
deba@2467
   612
    /// of this map. Otherwise if the \c forceLabel parameter was true
deba@2467
   613
    /// it will be sorted by its id in the graph.
deba@2467
   614
    void sortByLabel(std::vector<Edge>& edges) const {
deba@2467
   615
      uedgeset_writer.sortByLabel(edges);
deba@2467
   616
    }
deba@2467
   617
deba@2467
   618
    /// \brief Sorts the given undirected edge vector by label.
deba@2467
   619
    ///
deba@2467
   620
    /// Sorts the given undirected edge vector by label. If there was
deba@2467
   621
    /// written an "label" named map then the vector will be sorted by
deba@2467
   622
    /// the values of this map. Otherwise if the \c forceLabel
deba@2467
   623
    /// parameter was true it will be sorted by its id in the graph.
deba@2467
   624
    void sortByLabel(std::vector<UEdge>& uedges) const {
deba@2467
   625
      uedgeset_writer.sortByLabel(uedges);
deba@2467
   626
    }
deba@1429
   627
deba@1421
   628
  private:
deba@1421
   629
deba@1421
   630
    LemonWriter* writer;
deba@1421
   631
    bool own_writer;
deba@1421
   632
deba@1421
   633
    NodeSetWriter<Graph, WriterTraits> nodeset_writer;
deba@2467
   634
    UEdgeSetWriter<Graph, WriterTraits> uedgeset_writer;
deba@1421
   635
deba@1421
   636
    NodeWriter<Graph> node_writer;
deba@2467
   637
    UEdgeWriter<Graph> uedge_writer;
deba@1421
   638
    
deba@1421
   639
    AttributeWriter<WriterTraits> attribute_writer;
deba@1421
   640
  };
deba@1421
   641
deba@2502
   642
  /// \brief The bipartite graph writer class.
deba@2502
   643
  ///
deba@2502
   644
  /// The \c BpUGraphWriter class provides the ugraph output. To write 
deba@2502
   645
  /// a graph you should first give writing commands to the writer. You can 
deba@2502
   646
  /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap 
deba@2502
   647
  /// writing and labeled Node, Edge or UEdge writing.
deba@2502
   648
  ///
deba@2502
   649
  ///\code
deba@2502
   650
  /// BpUGraphWriter<ListUGraph> writer(std::cout, graph);
deba@2502
   651
  ///\endcode
deba@2502
   652
  ///
deba@2502
   653
  /// The \c writeNodeMap() function declares a \c NodeMap writing 
deba@2502
   654
  /// command in the \c BpUGraphWriter. You should give as parameter 
deba@2502
   655
  /// the name of the map and the map object. The NodeMap writing 
deba@2502
   656
  /// command with name "label" should write a unique map because it 
deba@2502
   657
  /// is regarded as label map.
deba@2502
   658
  ///
deba@2502
   659
  ///\code
deba@2502
   660
  /// IdMap<ListUGraph, Node> nodeLabelMap;
deba@2502
   661
  /// writer.writeNodeMap("label", nodeLabelMap);
deba@2502
   662
  ///
deba@2502
   663
  /// writer.writeNodeMap("coords", coords);
deba@2502
   664
  /// writer.writeNodeMap("color", colorMap);
deba@2502
   665
  ///\endcode
deba@2502
   666
  ///
deba@2502
   667
  /// With the \c writeUEdgeMap() member function you can give an 
deba@2502
   668
  /// undirected edge map writing command similar to the NodeMaps.
deba@2502
   669
  ///
deba@2502
   670
  ///\code
deba@2502
   671
  /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
deba@2502
   672
  ///   edgeDescMap(graph);
deba@2502
   673
  /// writer.writeUEdgeMap("descriptor", edgeDescMap);
deba@2502
   674
  ///
deba@2502
   675
  /// writer.writeUEdgeMap("weight", weightMap);
deba@2502
   676
  /// writer.writeUEdgeMap("label", labelMap);
deba@2502
   677
  ///\endcode
deba@2502
   678
  /// 
deba@2502
   679
  /// The EdgeMap handling is just a syntactical sugar. It writes
deba@2502
   680
  /// two undirected edge map with '+' and '-' prefix in the name.
deba@2502
   681
  ///
deba@2502
   682
  ///\code
deba@2502
   683
  /// writer.writeEdgeMap("capacity", capacityMap);
deba@2502
   684
  ///\endcode
deba@2502
   685
  ///
deba@2502
   686
  ///
deba@2502
   687
  /// With \c writeNode() and \c writeUEdge() functions you can 
deba@2502
   688
  /// designate nodes and undirected edges in the graph. For example, you can 
deba@2502
   689
  /// write out the source and target of the graph.
deba@2502
   690
  ///
deba@2502
   691
  ///\code
deba@2502
   692
  /// writer.writeNode("source", sourceNode);
deba@2502
   693
  /// writer.writeNode("target", targetNode);
deba@2502
   694
  ///
deba@2502
   695
  /// writer.writeUEdge("observed", uEdge);
deba@2502
   696
  ///\endcode
deba@2502
   697
  ///
deba@2502
   698
  /// After you give all write commands you must call the \c run() member
deba@2502
   699
  /// function, which executes all the writing commands.
deba@2502
   700
  ///
deba@2502
   701
  ///\code
deba@2502
   702
  /// writer.run();
deba@2502
   703
  ///\endcode
deba@2502
   704
  ///
deba@2502
   705
  /// \see DefaultWriterTraits
deba@2502
   706
  /// \see QuotedStringWriter
deba@2502
   707
  /// \see IdMap
deba@2502
   708
  /// \see DescriptorMap
deba@2502
   709
  /// \see \ref GraphWriter
deba@2502
   710
  /// \see \ref graph-io-page
deba@2502
   711
  /// \author Balazs Dezso
deba@2502
   712
  template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
deba@2502
   713
  class BpUGraphWriter {
deba@2502
   714
  public:
deba@2502
   715
    
deba@2502
   716
    typedef _Graph Graph;
deba@2502
   717
    typedef typename Graph::Node Node;
deba@2502
   718
    typedef typename Graph::Edge Edge;
deba@2502
   719
    typedef typename Graph::UEdge UEdge;
deba@2502
   720
deba@2502
   721
    typedef _WriterTraits WriterTraits;
deba@2502
   722
deba@2502
   723
    /// \brief Construct a new BpUGraphWriter.
deba@2502
   724
    ///
deba@2502
   725
    /// Construct a new BpUGraphWriter. It writes the given graph
deba@2502
   726
    /// to the given stream.
deba@2502
   727
    BpUGraphWriter(std::ostream& _os, const Graph& _graph) 
deba@2502
   728
      : writer(new LemonWriter(_os)), own_writer(true), 
deba@2502
   729
	nodeset_writer(*writer, _graph, std::string()),
deba@2502
   730
	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
deba@2502
   731
	node_writer(*writer, nodeset_writer, std::string()),
deba@2502
   732
	uedge_writer(*writer, uedgeset_writer, std::string()),
deba@2502
   733
	attribute_writer(*writer, std::string()) {}
deba@2502
   734
deba@2502
   735
    /// \brief Construct a new BpUGraphWriter.
deba@2502
   736
    ///
deba@2502
   737
    /// Construct a new BpUGraphWriter. It writes the given graph
deba@2502
   738
    /// to the given file.
deba@2502
   739
    BpUGraphWriter(const std::string& _filename, const Graph& _graph) 
deba@2502
   740
      : writer(new LemonWriter(_filename)), own_writer(true), 
deba@2502
   741
	nodeset_writer(*writer, _graph, std::string()),
deba@2502
   742
	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
deba@2502
   743
	node_writer(*writer, nodeset_writer, std::string()),
deba@2502
   744
	uedge_writer(*writer, uedgeset_writer, std::string()),
deba@2502
   745
	attribute_writer(*writer, std::string()) {}
deba@2502
   746
deba@2502
   747
    /// \brief Construct a new BpUGraphWriter.
deba@2502
   748
    ///
deba@2502
   749
    /// Construct a new BpUGraphWriter. It writes the given graph
deba@2502
   750
    /// to given LemonWriter.
deba@2502
   751
    BpUGraphWriter(LemonWriter& _writer, const Graph& _graph)
deba@2502
   752
      : writer(_writer), own_writer(false), 
deba@2502
   753
	nodeset_writer(*writer, _graph, std::string()),
deba@2502
   754
	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
deba@2502
   755
	node_writer(*writer, nodeset_writer, std::string()),
deba@2502
   756
	uedge_writer(*writer, uedgeset_writer, std::string()),
deba@2502
   757
	attribute_writer(*writer, std::string()) {}
deba@2502
   758
deba@2502
   759
    /// \brief Destruct the graph writer.
deba@2502
   760
    ///
deba@2502
   761
    /// Destruct the graph writer.
deba@2502
   762
    ~BpUGraphWriter() {
deba@2502
   763
      if (own_writer) 
deba@2502
   764
	delete writer;
deba@2502
   765
    }
deba@2502
   766
deba@2502
   767
    /// \brief Issue a new node map writing command to the writer.
deba@2502
   768
    ///
deba@2502
   769
    /// This function issues a new <i> node map writing command</i> to
deba@2502
   770
    /// the writer.
deba@2502
   771
    template <typename Map>
deba@2502
   772
    BpUGraphWriter& writeNodeMap(std::string label, const Map& map) {
deba@2502
   773
      nodeset_writer.writeNodeMap(label, map);
deba@2502
   774
      return *this;
deba@2502
   775
    }
deba@2502
   776
deba@2502
   777
    /// \brief Issue a new node map writing command to the writer.
deba@2502
   778
    ///
deba@2502
   779
    /// This function issues a new <i> node map writing command</i> to
deba@2502
   780
    /// the writer.
deba@2502
   781
    template <typename ItemWriter, typename Map>
deba@2502
   782
    BpUGraphWriter& writeNodeMap(std::string label, const Map& map, 
deba@2502
   783
			      const ItemWriter& iw = ItemWriter()) {
deba@2502
   784
      nodeset_writer.writeNodeMap(label, map, iw);
deba@2502
   785
      return *this;
deba@2502
   786
    }
deba@2502
   787
deba@2502
   788
    /// \brief Issue a new A-node map writing command to the writer.
deba@2502
   789
    ///
deba@2502
   790
    /// This function issues a new <i> A-node map writing command</i> to
deba@2502
   791
    /// the writer.
deba@2502
   792
    template <typename Map>
deba@2502
   793
    BpUGraphWriter& writeANodeMap(std::string label, const Map& map) {
deba@2502
   794
      nodeset_writer.writeANodeMap(label, map);
deba@2502
   795
      return *this;
deba@2502
   796
    }
deba@2502
   797
deba@2502
   798
    /// \brief Issue a new A-node map writing command to the writer.
deba@2502
   799
    ///
deba@2502
   800
    /// This function issues a new <i> A-node map writing command</i> to
deba@2502
   801
    /// the writer.
deba@2502
   802
    template <typename ItemWriter, typename Map>
deba@2502
   803
    BpUGraphWriter& writeANodeMap(std::string label, const Map& map, 
deba@2502
   804
			      const ItemWriter& iw = ItemWriter()) {
deba@2502
   805
      nodeset_writer.writeANodeMap(label, map, iw);
deba@2502
   806
      return *this;
deba@2502
   807
    }
deba@2502
   808
    /// \brief Issue a new B-node map writing command to the writer.
deba@2502
   809
    ///
deba@2502
   810
    /// This function issues a new <i> B-node map writing command</i> to
deba@2502
   811
    /// the writer.
deba@2502
   812
    template <typename Map>
deba@2502
   813
    BpUGraphWriter& writeBNodeMap(std::string label, const Map& map) {
deba@2502
   814
      nodeset_writer.writeBNodeMap(label, map);
deba@2502
   815
      return *this;
deba@2502
   816
    }
deba@2502
   817
deba@2502
   818
    /// \brief Issue a new B-node map writing command to the writer.
deba@2502
   819
    ///
deba@2502
   820
    /// This function issues a new <i> B-node map writing command</i> to
deba@2502
   821
    /// the writer.
deba@2502
   822
    template <typename ItemWriter, typename Map>
deba@2502
   823
    BpUGraphWriter& writeBNodeMap(std::string label, const Map& map, 
deba@2502
   824
			      const ItemWriter& iw = ItemWriter()) {
deba@2502
   825
      nodeset_writer.writeBNodeMap(label, map, iw);
deba@2502
   826
      return *this;
deba@2502
   827
    }
deba@2502
   828
deba@2502
   829
    /// \brief Issue a new edge map writing command to the writer.
deba@2502
   830
    ///
deba@2502
   831
    /// This function issues a new <i> edge map writing command</i> to
deba@2502
   832
    /// the writer.
deba@2502
   833
    template <typename Map>
deba@2502
   834
    BpUGraphWriter& writeEdgeMap(std::string label, const Map& map) { 
deba@2502
   835
      uedgeset_writer.writeEdgeMap(label, map);
deba@2502
   836
      return *this;
deba@2502
   837
    }
deba@2502
   838
deba@2502
   839
    /// \brief Issue a new edge map writing command to the writer.
deba@2502
   840
    ///
deba@2502
   841
    /// This function issues a new <i> edge map writing command</i> to
deba@2502
   842
    /// the writer.
deba@2502
   843
    template <typename ItemWriter, typename Map>
deba@2502
   844
    BpUGraphWriter& writeEdgeMap(std::string label, const Map& map,
deba@2502
   845
				   const ItemWriter& iw = ItemWriter()) {
deba@2502
   846
      uedgeset_writer.writeEdgeMap(label, map, iw);
deba@2502
   847
      return *this;
deba@2502
   848
    }
deba@2502
   849
deba@2502
   850
    /// \brief Issue a new undirected edge map writing command to the writer.
deba@2502
   851
    ///
deba@2502
   852
    /// This function issues a new <i> undirected edge map writing
deba@2502
   853
    /// command</i> to the writer.
deba@2502
   854
    template <typename Map>
deba@2502
   855
    BpUGraphWriter& writeUEdgeMap(std::string label, const Map& map) { 
deba@2502
   856
      uedgeset_writer.writeUEdgeMap(label, map);
deba@2502
   857
      return *this;
deba@2502
   858
    }
deba@2502
   859
deba@2502
   860
    /// \brief Issue a new undirected edge map writing command to the writer.
deba@2502
   861
    ///
deba@2502
   862
    /// This function issues a new <i> undirected edge map writing
deba@2502
   863
    /// command</i> to the writer.
deba@2502
   864
   template <typename ItemWriter, typename Map>
deba@2502
   865
    BpUGraphWriter& writeUEdgeMap(std::string label, const Map& map,
deba@2502
   866
					const ItemWriter& iw = ItemWriter()) {
deba@2502
   867
      uedgeset_writer.writeUEdgeMap(label, map, iw);
deba@2502
   868
      return *this;
deba@2502
   869
    }
deba@2502
   870
deba@2502
   871
    /// \brief Issue a new labeled node writer to the writer.
deba@2502
   872
    ///
deba@2502
   873
    /// This function issues a new <i> labeled node writing
deba@2502
   874
    /// command</i> to the writer.
deba@2502
   875
    BpUGraphWriter& writeNode(std::string label, const Node& node) {
deba@2502
   876
      node_writer.writeNode(label, node);
deba@2502
   877
      return *this;
deba@2502
   878
    }
deba@2502
   879
deba@2502
   880
    /// \brief Issue a new labeled edge writer to the writer.
deba@2502
   881
    ///
deba@2502
   882
    /// This function issues a new <i> labeled edge writing
deba@2502
   883
    /// command</i> to the writer.
deba@2502
   884
    BpUGraphWriter& writeEdge(std::string label, const Edge& edge) {
deba@2502
   885
      uedge_writer.writeEdge(label, edge);
deba@2502
   886
    }
deba@2502
   887
deba@2502
   888
    /// \brief Issue a new labeled undirected edge writing command to
deba@2502
   889
    /// the writer.
deba@2502
   890
    ///
deba@2502
   891
    /// Issue a new <i>labeled undirected edge writing command</i> to
deba@2502
   892
    /// the writer.
deba@2502
   893
    BpUGraphWriter& writeUEdge(std::string label, const UEdge& edge) {
deba@2502
   894
      uedge_writer.writeUEdge(label, edge);
deba@2502
   895
    }
deba@2502
   896
deba@2502
   897
    /// \brief Issue a new attribute writing command.
deba@2502
   898
    ///
deba@2502
   899
    /// This function issues a new <i> attribute writing
deba@2502
   900
    /// command</i> to the writer.
deba@2502
   901
    template <typename Value>
deba@2502
   902
    BpUGraphWriter& writeAttribute(std::string label, const Value& value) {
deba@2502
   903
      attribute_writer.writeAttribute(label, value);
deba@2502
   904
      return *this;
deba@2502
   905
    }
deba@2502
   906
    
deba@2502
   907
    /// \brief Issue a new attribute writing command.
deba@2502
   908
    ///
deba@2502
   909
    /// This function issues a new <i> attribute writing
deba@2502
   910
    /// command</i> to the writer.
deba@2502
   911
    template <typename ItemWriter, typename Value>
deba@2502
   912
    BpUGraphWriter& writeAttribute(std::string label, const Value& value, 
deba@2502
   913
			       const ItemWriter& iw = ItemWriter()) {
deba@2502
   914
      attribute_writer.writeAttribute(label, value, iw);
deba@2502
   915
      return *this;
deba@2502
   916
    }
deba@2502
   917
deba@2502
   918
    /// \brief Conversion operator to LemonWriter.
deba@2502
   919
    ///
deba@2502
   920
    /// Conversion operator to LemonWriter. It makes possible
deba@2502
   921
    /// to access the encapsulated \e LemonWriter, this way
deba@2502
   922
    /// you can attach to this writer new instances of 
deba@2502
   923
    /// \e LemonWriter::SectionWriter.
deba@2502
   924
    operator LemonWriter&() {
deba@2502
   925
      return *writer;
deba@2502
   926
    }
deba@2502
   927
deba@2502
   928
    /// \brief Executes the writing commands.
deba@2502
   929
    ///
deba@2502
   930
    /// Executes the writing commands.
deba@2502
   931
    void run() {
deba@2502
   932
      writer->run();
deba@2502
   933
    }
deba@2502
   934
deba@2502
   935
    /// \brief Returns true if the writer can give back the labels by the items.
deba@2502
   936
    ///
deba@2502
   937
    /// Returns true if the writer can give back the the labels by the items.
deba@2502
   938
    bool isLabelWriter() const {
deba@2502
   939
      return nodeset_writer.isLabelWriter() && 
deba@2502
   940
        uedgeset_writer.isLabelWriter();
deba@2502
   941
    }
deba@2502
   942
deba@2502
   943
    /// \brief Write the label of the given node.
deba@2502
   944
    ///
deba@2502
   945
    /// It writes the label of the given node. If there was written a "label"
deba@2502
   946
    /// named node map then it will write the map value belonging to the node.
deba@2502
   947
    void writeLabel(std::ostream& os, const Node& item) const {
deba@2502
   948
      nodeset_writer.writeLabel(os, item);
deba@2502
   949
    } 
deba@2502
   950
deba@2502
   951
    /// \brief Write the label of the given edge.
deba@2502
   952
    ///
deba@2502
   953
    /// It writes the label of the given edge. If there was written a "label"
deba@2502
   954
    /// named edge map then it will write the map value belonging to the edge.
deba@2502
   955
    void writeLabel(std::ostream& os, const Edge& item) const {
deba@2502
   956
      uedgeset_writer.writeLabel(os, item);
deba@2502
   957
    } 
deba@2502
   958
deba@2502
   959
    /// \brief Write the label of the given undirected edge.
deba@2502
   960
    ///
deba@2502
   961
    /// It writes the label of the given undirected edge. If there was
deba@2502
   962
    /// written a "label" named edge map then it will write the map
deba@2502
   963
    /// value belonging to the edge.
deba@2502
   964
    void writeLabel(std::ostream& os, const UEdge& item) const {
deba@2502
   965
      uedgeset_writer.writeLabel(os, item);
deba@2502
   966
    } 
deba@2502
   967
deba@2502
   968
    /// \brief Sorts the given node vector by label.
deba@2502
   969
    ///
deba@2502
   970
    /// Sorts the given node vector by label. If there was written an
deba@2502
   971
    /// "label" named map then the vector will be sorted by the values
deba@2502
   972
    /// of this map. Otherwise if the \c forceLabel parameter was true
deba@2502
   973
    /// it will be sorted by its id in the graph.
deba@2502
   974
    void sortByLabel(std::vector<Node>& nodes) const {
deba@2502
   975
      nodeset_writer.sortByLabel(nodes);
deba@2502
   976
    }
deba@2502
   977
deba@2502
   978
    /// \brief Sorts the given edge vector by label.
deba@2502
   979
    ///
deba@2502
   980
    /// Sorts the given edge vector by label. If there was written an
deba@2502
   981
    /// "label" named map then the vector will be sorted by the values
deba@2502
   982
    /// of this map. Otherwise if the \c forceLabel parameter was true
deba@2502
   983
    /// it will be sorted by its id in the graph.
deba@2502
   984
    void sortByLabel(std::vector<Edge>& edges) const {
deba@2502
   985
      uedgeset_writer.sortByLabel(edges);
deba@2502
   986
    }
deba@2502
   987
deba@2502
   988
    /// \brief Sorts the given undirected edge vector by label.
deba@2502
   989
    ///
deba@2502
   990
    /// Sorts the given undirected edge vector by label. If there was
deba@2502
   991
    /// written an "label" named map then the vector will be sorted by
deba@2502
   992
    /// the values of this map. Otherwise if the \c forceLabel
deba@2502
   993
    /// parameter was true it will be sorted by its id in the graph.
deba@2502
   994
    void sortByLabel(std::vector<UEdge>& uedges) const {
deba@2502
   995
      uedgeset_writer.sortByLabel(uedges);
deba@2502
   996
    }
deba@2502
   997
deba@2502
   998
  private:
deba@2502
   999
deba@2502
  1000
    LemonWriter* writer;
deba@2502
  1001
    bool own_writer;
deba@2502
  1002
deba@2502
  1003
    BpNodeSetWriter<Graph, WriterTraits> nodeset_writer;
deba@2502
  1004
    UEdgeSetWriter<Graph, WriterTraits> uedgeset_writer;
deba@2502
  1005
deba@2502
  1006
    NodeWriter<Graph> node_writer;
deba@2502
  1007
    UEdgeWriter<Graph> uedge_writer;
deba@2502
  1008
    
deba@2502
  1009
    AttributeWriter<WriterTraits> attribute_writer;
deba@2502
  1010
  };
deba@2502
  1011
deba@1333
  1012
  /// @}
deba@1137
  1013
deba@1137
  1014
}
deba@1214
  1015
deba@1214
  1016
#endif