lemon/graph_reader.h
author deba
Mon, 12 Sep 2005 09:15:59 +0000
changeset 1679 e825655c24a4
parent 1534 b86aad11f842
child 1705 3f63d9db307b
permissions -rw-r--r--
Some bugfixes.
deba@1137
     1
/* -*- C++ -*-
ladanyi@1435
     2
 * lemon/graph_reader.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 reader.
deba@1137
    20
deba@1214
    21
#ifndef LEMON_GRAPH_READER_H
deba@1214
    22
#define LEMON_GRAPH_READER_H
deba@1214
    23
deba@1137
    24
#include <iostream>
deba@1137
    25
deba@1137
    26
#include <lemon/error.h>
deba@1408
    27
#include <lemon/lemon_reader.h>
deba@1137
    28
deba@1137
    29
namespace lemon {
deba@1137
    30
deba@1333
    31
  /// \addtogroup io_group
deba@1333
    32
  /// @{
deba@1137
    33
deba@1137
    34
  /// \brief The graph reader class.
deba@1137
    35
  ///
athos@1534
    36
  /// The \c GraphReader class provides the graph input. 
athos@1534
    37
  /// Before you read this documentation it might be useful to read the general
athos@1534
    38
  /// description of  \ref graph-io-page "Graph Input-Output".
athos@1540
    39
  ///
athos@1534
    40
  /// If you don't need very sophisticated
athos@1534
    41
  /// behaviour then you can use the versions of the public function
athos@1534
    42
  /// \ref readGraph() to read a graph (or a max flow instance etc).
athos@1534
    43
  ///
athos@1540
    44
  /// The file to be read may contain several maps and labeled nodes or 
deba@1333
    45
  /// edges.
deba@1333
    46
  ///
deba@1333
    47
  /// If you read a graph you need not read all the maps and items just those
deba@1333
    48
  /// that you need. The interface of the \c GraphReader is very similar to
deba@1333
    49
  /// the GraphWriter but the reading method does not depend on the order the
athos@1540
    50
  /// given commands (i.e. you don't have to insist on the order in which the
athos@1540
    51
  /// maps are given in the file).
deba@1333
    52
  ///
athos@1540
    53
  /// The reader object assumes that not readed values do not contain 
deba@1333
    54
  /// whitespaces, therefore it has some extra possibilities to control how
deba@1333
    55
  /// it should skip the values when the string representation contains spaces.
deba@1333
    56
  ///
deba@1333
    57
  /// \code
deba@1333
    58
  /// GraphReader<ListGraph> reader(std::cin, graph);
deba@1333
    59
  /// \endcode
deba@1333
    60
  ///
deba@1394
    61
  /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
deba@1333
    62
  /// If there is a map that you do not want to read from the file and there is
deba@1333
    63
  /// whitespace in the string represenation of the values then you should
deba@1333
    64
  /// call the \c skipNodeMap() template member function with proper 
deba@1333
    65
  /// parameters.
deba@1333
    66
  ///
deba@1333
    67
  /// \code
deba@1421
    68
  /// reader.readNodeMap("coords", coords);
deba@1333
    69
  ///
deba@1394
    70
  /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
deba@1333
    71
  /// reader.skipNodeMap<QuotedStringReader>("description");
deba@1333
    72
  ///
deba@1394
    73
  /// reader.readNodeMap("color", colorMap);
deba@1333
    74
  /// \endcode
deba@1333
    75
  ///
deba@1394
    76
  /// With the \c readEdgeMap() member function you can give an edge map
deba@1333
    77
  /// reading command similar to the NodeMaps. 
deba@1333
    78
  ///
deba@1333
    79
  /// \code
deba@1394
    80
  /// reader.readEdgeMap("weight", weightMap);
deba@1394
    81
  /// reader.readEdgeMap("label", labelMap);
deba@1333
    82
  /// \endcode
deba@1333
    83
  ///
deba@1408
    84
  /// With \c readNode() and \c readEdge() functions you can read 
deba@1408
    85
  /// labeled Nodes and Edges.
deba@1333
    86
  ///
deba@1333
    87
  /// \code
deba@1394
    88
  /// reader.readNode("source", sourceNode);
deba@1394
    89
  /// reader.readNode("target", targetNode);
deba@1333
    90
  ///
deba@1394
    91
  /// reader.readEdge("observed", edge);
deba@1333
    92
  /// \endcode
deba@1333
    93
  ///
deba@1408
    94
  /// With the \c readAttribute() functions you can read an attribute
athos@1540
    95
  /// into a variable. You can specify the reader for the attribute as
deba@1408
    96
  /// the nodemaps.
deba@1408
    97
  ///
deba@1333
    98
  /// After you give all read commands you must call the \c run() member
athos@1540
    99
  /// function, which executes all the commands.
deba@1333
   100
  ///
deba@1333
   101
  /// \code
deba@1333
   102
  /// reader.run();
deba@1333
   103
  /// \endcode
deba@1333
   104
  ///
alpar@1287
   105
  /// \see DefaultReaderTraits
alpar@1287
   106
  /// \see QuotedStringReader
alpar@1138
   107
  /// \see \ref GraphWriter
alpar@1138
   108
  /// \see \ref graph-io-page
deba@1333
   109
  /// \author Balazs Dezso
deba@1137
   110
  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
deba@1137
   111
  class GraphReader {
deba@1137
   112
  public:
deba@1137
   113
    
deba@1137
   114
    typedef _Graph Graph;
deba@1137
   115
    typedef typename Graph::Node Node;
deba@1137
   116
    typedef typename Graph::Edge Edge;
deba@1137
   117
deba@1137
   118
    typedef _ReaderTraits ReaderTraits;
deba@1408
   119
    typedef typename ReaderTraits::Skipper DefaultSkipper;
deba@1137
   120
deba@1137
   121
    /// \brief Construct a new GraphReader.
deba@1137
   122
    ///
deba@1208
   123
    /// Construct a new GraphReader. It reads into the given graph
athos@1540
   124
    /// and it uses the given reader as the default skipper.
deba@1421
   125
    GraphReader(std::istream& _is, 
deba@1421
   126
		typename SmartParameter<Graph>::Type _graph, 
deba@1408
   127
		const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421
   128
      : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
deba@1421
   129
	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421
   130
	edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421
   131
		       std::string(), skipper),
deba@1408
   132
	node_reader(*reader, nodeset_reader, std::string()),
deba@1408
   133
	edge_reader(*reader, edgeset_reader, std::string()),
deba@1408
   134
	attribute_reader(*reader, std::string()) {}
deba@1408
   135
deba@1408
   136
    /// \brief Construct a new GraphReader.
deba@1408
   137
    ///
deba@1408
   138
    /// Construct a new GraphReader. It reads into the given graph
athos@1540
   139
    /// and it uses the given reader as the default skipper.
deba@1421
   140
    GraphReader(const std::string& _filename, 
deba@1421
   141
		typename SmartParameter<Graph>::Type _graph, 
deba@1408
   142
		const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1408
   143
      : reader(new LemonReader(_filename)), own_reader(true), 
deba@1421
   144
	skipper(_skipper),
deba@1421
   145
	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421
   146
	edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421
   147
		       std::string(), skipper),
deba@1408
   148
	node_reader(*reader, nodeset_reader, std::string()),
deba@1408
   149
	edge_reader(*reader, edgeset_reader, std::string()),
deba@1408
   150
	attribute_reader(*reader, std::string()) {}
deba@1408
   151
deba@1408
   152
    /// \brief Construct a new GraphReader.
deba@1408
   153
    ///
deba@1408
   154
    /// Construct a new GraphReader. It reads into the given graph
athos@1540
   155
    /// and it uses the given reader as the default skipper.
deba@1421
   156
    GraphReader(LemonReader& _reader, 
deba@1421
   157
		typename SmartParameter<Graph>::Type _graph, 
deba@1408
   158
		const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421
   159
      : reader(_reader), own_reader(false), skipper(_skipper),
deba@1421
   160
	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421
   161
	edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421
   162
		       std::string(), skipper),
deba@1408
   163
	node_reader(*reader, nodeset_reader, std::string()),
deba@1408
   164
	edge_reader(*reader, edgeset_reader, std::string()),
deba@1408
   165
	attribute_reader(*reader, std::string()) {}
deba@1137
   166
deba@1137
   167
    /// \brief Destruct the graph reader.
deba@1137
   168
    ///
deba@1137
   169
    /// Destruct the graph reader.
deba@1137
   170
    ~GraphReader() {
deba@1408
   171
      if (own_reader) 
deba@1408
   172
	delete reader;
deba@1137
   173
    }
deba@1137
   174
athos@1540
   175
    /// \brief Give a new node map reading command to the reader.
deba@1137
   176
    ///
athos@1540
   177
    /// Give a new node map reading command to the reader.
deba@1137
   178
    template <typename Map>
deba@1394
   179
    GraphReader& readNodeMap(std::string name, Map& map) {
deba@1421
   180
      nodeset_reader.readNodeMap(name, map);
deba@1421
   181
      return *this;
deba@1421
   182
    }
deba@1421
   183
deba@1421
   184
    template <typename Map>
deba@1421
   185
    GraphReader& readNodeMap(std::string name, const Map& map) {
deba@1421
   186
      nodeset_reader.readNodeMap(name, map);
deba@1408
   187
      return *this;
deba@1137
   188
    }
deba@1137
   189
athos@1540
   190
    /// \brief Give a new node map reading command to the reader.
deba@1137
   191
    ///
athos@1540
   192
    /// Give a new node map reading command to the reader.
deba@1137
   193
    template <typename Reader, typename Map>
deba@1394
   194
    GraphReader& readNodeMap(std::string name, Map& map, 
deba@1137
   195
			     const Reader& reader = Reader()) {
deba@1421
   196
      nodeset_reader.readNodeMap(name, map, reader);
deba@1421
   197
      return *this;
deba@1421
   198
    }
deba@1421
   199
deba@1421
   200
    template <typename Reader, typename Map>
deba@1421
   201
    GraphReader& readNodeMap(std::string name, const Map& map, 
deba@1421
   202
			     const Reader& reader = Reader()) {
deba@1421
   203
      nodeset_reader.readNodeMap(name, map, reader);
deba@1137
   204
      return *this;
deba@1137
   205
    }
deba@1137
   206
athos@1540
   207
    /// \brief Give a new node map skipping command to the reader.
deba@1137
   208
    ///
athos@1540
   209
    /// Give a new node map skipping command to the reader.
deba@1137
   210
    template <typename Reader>
deba@1137
   211
    GraphReader& skipNodeMap(std::string name, 
deba@1137
   212
			     const Reader& reader = Reader()) {
deba@1421
   213
      nodeset_reader.skipNodeMap(name, reader);
deba@1137
   214
      return *this;
deba@1137
   215
    }
deba@1137
   216
athos@1540
   217
    /// \brief Give a new edge map reading command to the reader.
deba@1137
   218
    ///
athos@1540
   219
    /// Give a new edge map reading command to the reader.
deba@1137
   220
    template <typename Map>
deba@1394
   221
    GraphReader& readEdgeMap(std::string name, Map& map) { 
deba@1421
   222
      edgeset_reader.readEdgeMap(name, map);
deba@1421
   223
      return *this;
deba@1421
   224
    }
deba@1421
   225
deba@1421
   226
    template <typename Map>
deba@1421
   227
    GraphReader& readEdgeMap(std::string name, const Map& map) { 
deba@1421
   228
      edgeset_reader.readEdgeMap(name, map);
deba@1408
   229
      return *this;
deba@1137
   230
    }
deba@1137
   231
deba@1137
   232
athos@1540
   233
    /// \brief Give a new edge map reading command to the reader.
deba@1137
   234
    ///
athos@1540
   235
    /// Give a new edge map reading command to the reader.
deba@1137
   236
    template <typename Reader, typename Map>
deba@1394
   237
    GraphReader& readEdgeMap(std::string name, Map& map,
deba@1137
   238
			     const Reader& reader = Reader()) {
deba@1421
   239
      edgeset_reader.readEdgeMap(name, map, reader);
deba@1421
   240
      return *this;
deba@1421
   241
    }
deba@1421
   242
deba@1421
   243
    template <typename Reader, typename Map>
deba@1421
   244
    GraphReader& readEdgeMap(std::string name, const Map& map,
deba@1421
   245
			     const Reader& reader = Reader()) {
deba@1421
   246
      edgeset_reader.readEdgeMap(name, map, reader);
deba@1137
   247
      return *this;
deba@1137
   248
    }
deba@1137
   249
athos@1540
   250
    /// \brief Give a new edge map skipping command to the reader.
deba@1137
   251
    ///
athos@1540
   252
    /// Give a new edge map skipping command to the reader.
deba@1137
   253
    template <typename Reader>
deba@1421
   254
    GraphReader& skipEdgeMap(std::string name, 
deba@1137
   255
			     const Reader& reader = Reader()) {
deba@1421
   256
      edgeset_reader.skipEdgeMap(name, reader);
deba@1137
   257
      return *this;
deba@1137
   258
    }
deba@1137
   259
athos@1540
   260
    /// \brief Give a new labeled node reading command to the reader.
deba@1137
   261
    ///
athos@1540
   262
    /// Give a new labeled node reading command to the reader.
deba@1394
   263
    GraphReader& readNode(std::string name, Node& node) {
deba@1408
   264
      node_reader.readNode(name, node);
deba@1137
   265
      return *this;
deba@1137
   266
    }
deba@1137
   267
athos@1540
   268
    /// \brief Give a new labeled edge reading command to the reader.
deba@1137
   269
    ///
athos@1540
   270
    /// Give a new labeled edge reading command to the reader.
deba@1394
   271
    GraphReader& readEdge(std::string name, Edge& edge) {
deba@1408
   272
      edge_reader.readEdge(name, edge);
deba@1476
   273
      return *this;
deba@1408
   274
    }
deba@1408
   275
athos@1540
   276
    /// \brief Give a new attribute reading command.
deba@1408
   277
    ///
athos@1540
   278
    ///  Give a new attribute reading command.
deba@1408
   279
    template <typename Value>
deba@1408
   280
    GraphReader& readAttribute(std::string name, Value& value) {
deba@1408
   281
      attribute_reader.readAttribute(name, value);
deba@1137
   282
      return *this;
deba@1137
   283
    }
deba@1408
   284
    
athos@1540
   285
    /// \brief Give a new attribute reading command.
deba@1408
   286
    ///
athos@1540
   287
    ///  Give a new attribute reading command.
deba@1408
   288
    template <typename Reader, typename Value>
deba@1408
   289
    GraphReader& readAttribute(std::string name, Value& value, 
deba@1408
   290
			       const Reader& reader) {
deba@1408
   291
      attribute_reader.readAttribute<Reader>(name, value, reader);
deba@1408
   292
      return *this;
deba@1408
   293
    }
deba@1408
   294
deba@1408
   295
    /// \brief Conversion operator to LemonReader.
deba@1408
   296
    ///
athos@1540
   297
    /// Conversion operator to LemonReader. It makes possible to access the
athos@1540
   298
    /// encapsulated \e LemonReader, this way you can attach to this reader
athos@1540
   299
    /// new instances of \e LemonReader::SectionReader. For more details see
athos@1540
   300
    /// the \ref rwbackground "Background of Reading and Writing".
deba@1408
   301
    operator LemonReader&() {
deba@1408
   302
      return *reader;
deba@1408
   303
    }
deba@1137
   304
athos@1540
   305
    /// \brief Executes the reading commands.
deba@1137
   306
    ///
athos@1540
   307
    /// Executes the reading commands.
deba@1137
   308
    void run() {
deba@1408
   309
      reader->run();
deba@1396
   310
    }
deba@1396
   311
deba@1429
   312
    /// \brief Gives back the node by its id.
deba@1429
   313
    ///
deba@1429
   314
    /// It reads an id from the stream and gives back which node belongs to
deba@1429
   315
    /// it. It is possible only if there was read an "id" named node map.
deba@1429
   316
    Node readId(std::istream& is, Node) const {
deba@1429
   317
      return nodeset_reader.readId(is, Node());
deba@1429
   318
    } 
deba@1429
   319
deba@1429
   320
    /// \brief Gives back the edge by its id.
deba@1429
   321
    ///
deba@1429
   322
    /// It reads an id from the stream and gives back which edge belongs to
deba@1429
   323
    /// it. It is possible only if there was read an "id" named edge map.
deba@1429
   324
    Edge readId(std::istream& is, Edge) const {
deba@1429
   325
      return edgeset_reader.readId(is, Edge());
deba@1429
   326
    } 
deba@1429
   327
deba@1137
   328
  private:
deba@1137
   329
deba@1408
   330
    LemonReader* reader;
deba@1408
   331
    bool own_reader;
deba@1137
   332
deba@1408
   333
    DefaultSkipper skipper;
deba@1137
   334
deba@1408
   335
    NodeSetReader<Graph, ReaderTraits> nodeset_reader;
deba@1408
   336
    EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
deba@1408
   337
deba@1408
   338
    NodeReader<Graph> node_reader;
deba@1408
   339
    EdgeReader<Graph> edge_reader;
deba@1408
   340
    
deba@1408
   341
    AttributeReader<ReaderTraits> attribute_reader;
deba@1137
   342
  };
deba@1137
   343
athos@1534
   344
athos@1534
   345
  ///\anchor readGraph()
deba@1333
   346
  ///
athos@1534
   347
  /// \brief Read a graph from an input stream.
athos@1534
   348
  ///
athos@1534
   349
  /// Read a graph from an input stream.
athos@1534
   350
  /// \param is The input stream.
athos@1534
   351
  /// \param g The graph.
athos@1534
   352
  template<typename Graph>
athos@1534
   353
  void readGraph(std::istream& is, Graph &g) {
athos@1534
   354
    GraphReader<Graph> reader(is, g);
athos@1534
   355
    reader.run();
athos@1534
   356
  }
athos@1534
   357
athos@1534
   358
  /// \brief Read a capacitated graph instance from an input stream.
athos@1534
   359
  /// 
athos@1534
   360
  /// Read a capacitated graph (graph+capacity on the
athos@1534
   361
  /// edges) from an input stream.
athos@1534
   362
  /// \param is The input stream.
athos@1534
   363
  /// \param g The graph.
athos@1534
   364
  /// \param capacity The capacity map.
athos@1534
   365
  template<typename Graph, typename CapacityMap>
athos@1534
   366
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
athos@1534
   367
    GraphReader<Graph> reader(is, g);
athos@1534
   368
    reader.readEdgeMap("capacity", capacity);
athos@1534
   369
    reader.run();
athos@1534
   370
  }
athos@1534
   371
athos@1534
   372
  /// \brief Read a shortest path instance from an input stream.
athos@1534
   373
  /// 
athos@1534
   374
  /// Read a shortest path instance (graph+capacity on the
athos@1534
   375
  /// edges+designated source) from an input stream.
athos@1534
   376
  /// \param is The input stream.
athos@1534
   377
  /// \param g The graph.
athos@1534
   378
  /// \param capacity The capacity map.
athos@1534
   379
  /// \param s The source node.
athos@1534
   380
  template<typename Graph, typename CapacityMap>
athos@1534
   381
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
athos@1534
   382
		  typename Graph::Node &s) {
athos@1534
   383
    GraphReader<Graph> reader(is, g);
athos@1534
   384
    reader.readEdgeMap("capacity", capacity);
athos@1534
   385
    reader.readNode("source", s);
athos@1534
   386
    reader.run();
athos@1534
   387
  }
athos@1534
   388
athos@1534
   389
athos@1534
   390
athos@1534
   391
  /// \brief Read a max flow instance from an input stream.
athos@1534
   392
  ///
athos@1534
   393
  /// Read a max flow instance (graph+capacity on the
athos@1534
   394
  /// edges+designated source and target) from an input stream.
athos@1534
   395
  ///
athos@1534
   396
  /// \param is The input stream.
athos@1534
   397
  /// \param g The graph.
athos@1534
   398
  /// \param capacity The capacity map.
athos@1534
   399
  /// \param s The source node.
athos@1534
   400
  /// \param t The target node.
athos@1534
   401
  template<typename Graph, typename CapacityMap>
athos@1534
   402
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
athos@1534
   403
		  typename Graph::Node &s, typename Graph::Node &t) {
athos@1534
   404
    GraphReader<Graph> reader(is, g);
athos@1534
   405
    reader.readEdgeMap("capacity", capacity);
athos@1534
   406
    reader.readNode("source", s);
athos@1534
   407
    reader.readNode("target", t);
athos@1534
   408
    reader.run();
athos@1534
   409
  }
athos@1534
   410
athos@1534
   411
  /// \brief Read a min cost flow instance from an input stream.
athos@1534
   412
  ///
athos@1534
   413
  /// Read a min cost flow instance (graph+capacity on the edges+cost
athos@1534
   414
  /// function on the edges+designated source and target) from an input stream.
athos@1534
   415
  ///
deba@1333
   416
  /// \param is The input stream.
deba@1333
   417
  /// \param g The graph.
deba@1333
   418
  /// \param capacity The capacity map.
deba@1333
   419
  /// \param s The source node.
deba@1333
   420
  /// \param t The target node.
deba@1333
   421
  /// \param cost The cost map.
deba@1208
   422
  template<typename Graph, typename CapacityMap, typename CostMap>
deba@1208
   423
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
deba@1208
   424
		  typename Graph::Node &s, typename Graph::Node &t, 
deba@1208
   425
		  CostMap& cost) {
deba@1208
   426
    GraphReader<Graph> reader(is, g);
deba@1394
   427
    reader.readEdgeMap("capacity", capacity);
deba@1394
   428
    reader.readEdgeMap("cost", cost);
deba@1394
   429
    reader.readNode("source", s);
deba@1394
   430
    reader.readNode("target", t);
deba@1208
   431
    reader.run();
deba@1208
   432
  }
deba@1208
   433
deba@1208
   434
deba@1421
   435
  /// \brief The undir graph reader class.
deba@1421
   436
  ///
athos@1540
   437
  /// The \c UndirGraphReader class provides the graph input. 
athos@1540
   438
  /// Before you read this documentation it might be useful to read the general
athos@1540
   439
  /// description of  \ref graph-io-page "Graph Input-Output".
athos@1540
   440
  ///
athos@1540
   441
  /// If you don't need very sophisticated
athos@1540
   442
  /// behaviour then you can use the versions of the public function
athos@1540
   443
  /// \ref readGraph() to read a graph (or a max flow instance etc).
athos@1540
   444
  ///
deba@1421
   445
  /// The given file format may contain several maps and labeled nodes or 
deba@1421
   446
  /// edges.
deba@1421
   447
  ///
deba@1421
   448
  /// If you read a graph you need not read all the maps and items just those
athos@1540
   449
  /// that you need. The interface of the \c UndirGraphReader is very similar
athos@1540
   450
  /// to the UndirGraphWriter but the reading method does not depend on the
athos@1540
   451
  /// order of the given commands.
deba@1421
   452
  ///
deba@1421
   453
  /// The reader object suppose that each not readed value does not contain 
deba@1421
   454
  /// whitespaces, therefore it has some extra possibilities to control how
deba@1421
   455
  /// it should skip the values when the string representation contains spaces.
deba@1421
   456
  ///
deba@1421
   457
  /// \code
deba@1421
   458
  /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
deba@1421
   459
  /// \endcode
deba@1421
   460
  ///
deba@1421
   461
  /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
deba@1421
   462
  /// If there is a map that you do not want to read from the file and there is
deba@1421
   463
  /// whitespace in the string represenation of the values then you should
deba@1421
   464
  /// call the \c skipNodeMap() template member function with proper 
deba@1421
   465
  /// parameters.
deba@1421
   466
  ///
deba@1421
   467
  /// \code
deba@1421
   468
  /// reader.readNodeMap("coords", coords);
deba@1421
   469
  ///
deba@1421
   470
  /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
deba@1421
   471
  /// reader.skipNodeMap<QuotedStringReader>("description");
deba@1421
   472
  ///
deba@1421
   473
  /// reader.readNodeMap("color", colorMap);
deba@1421
   474
  /// \endcode
deba@1421
   475
  ///
deba@1421
   476
  /// With the \c readUndirEdgeMap() member function you can give an 
deba@1421
   477
  /// undir edge map reading command similar to the NodeMaps. 
deba@1421
   478
  ///
deba@1421
   479
  /// \code
deba@1421
   480
  /// reader.readUndirEdgeMap("capacity", capacityMap);
deba@1421
   481
  /// \endcode
deba@1421
   482
  ///
deba@1421
   483
  /// The reading of the directed edge maps is just a syntactical sugar.
deba@1421
   484
  /// It reads two undirected edgemaps into a directed edge map. The 
deba@1421
   485
  /// undirected edge maps' name should be start with the \c '+' and the
deba@1421
   486
  /// \c '-' character and the same.
deba@1421
   487
  ///
deba@1421
   488
  /// \code
deba@1421
   489
  /// reader.readEdgeMap("flow", flowMap);
deba@1421
   490
  /// \endcode 
deba@1421
   491
  ///
deba@1421
   492
  /// With \c readNode() and \c readUndirEdge() functions you can read 
deba@1421
   493
  /// labeled Nodes and UndirEdges.
deba@1421
   494
  ///
deba@1421
   495
  /// \code
deba@1421
   496
  /// reader.readNode("source", sourceNode);
deba@1421
   497
  /// reader.readNode("target", targetNode);
deba@1421
   498
  ///
deba@1421
   499
  /// reader.readUndirEdge("observed", undirEdge);
deba@1421
   500
  /// \endcode
deba@1421
   501
  ///
deba@1421
   502
  /// With the \c readAttribute() functions you can read an attribute
deba@1421
   503
  /// in a variable. You can specify the reader for the attribute as
deba@1421
   504
  /// the nodemaps.
deba@1421
   505
  ///
deba@1421
   506
  /// After you give all read commands you must call the \c run() member
deba@1421
   507
  /// function, which execute all the commands.
deba@1421
   508
  ///
deba@1421
   509
  /// \code
deba@1421
   510
  /// reader.run();
deba@1421
   511
  /// \endcode
deba@1421
   512
  ///
deba@1421
   513
  /// \see GraphReader
deba@1421
   514
  /// \see DefaultReaderTraits
deba@1421
   515
  /// \see \ref UndirGraphWriter
deba@1421
   516
  /// \see \ref graph-io-page
deba@1421
   517
  ///
deba@1421
   518
  /// \author Balazs Dezso
deba@1421
   519
  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
deba@1421
   520
  class UndirGraphReader {
deba@1421
   521
  public:
deba@1421
   522
    
deba@1421
   523
    typedef _Graph Graph;
deba@1421
   524
    typedef typename Graph::Node Node;
deba@1421
   525
    typedef typename Graph::Edge Edge;
deba@1421
   526
    typedef typename Graph::UndirEdge UndirEdge;
deba@1421
   527
deba@1421
   528
    typedef _ReaderTraits ReaderTraits;
deba@1421
   529
    typedef typename ReaderTraits::Skipper DefaultSkipper;
deba@1421
   530
deba@1421
   531
    /// \brief Construct a new UndirGraphReader.
deba@1421
   532
    ///
deba@1421
   533
    /// Construct a new UndirGraphReader. It reads into the given graph
deba@1421
   534
    /// and it use the given reader as the default skipper.
deba@1421
   535
    UndirGraphReader(std::istream& _is, Graph& _graph, 
deba@1421
   536
		     const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421
   537
      : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
deba@1421
   538
	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421
   539
	undir_edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421
   540
			     std::string(), skipper),
deba@1421
   541
	node_reader(*reader, nodeset_reader, std::string()),
deba@1421
   542
	undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
deba@1421
   543
	attribute_reader(*reader, std::string()) {}
deba@1421
   544
deba@1421
   545
    /// \brief Construct a new UndirGraphReader.
deba@1421
   546
    ///
deba@1421
   547
    /// Construct a new UndirGraphReader. It reads into the given graph
deba@1421
   548
    /// and it use the given reader as the default skipper.
deba@1421
   549
    UndirGraphReader(const std::string& _filename, Graph& _graph, 
deba@1421
   550
		     const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421
   551
      : reader(new LemonReader(_filename)), own_reader(true), 
deba@1421
   552
	skipper(_skipper),
deba@1421
   553
	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421
   554
	undir_edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421
   555
			     std::string(), skipper),
deba@1421
   556
	node_reader(*reader, nodeset_reader, std::string()),
deba@1421
   557
	undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
deba@1421
   558
	attribute_reader(*reader, std::string()) {}
deba@1421
   559
deba@1421
   560
    /// \brief Construct a new UndirGraphReader.
deba@1421
   561
    ///
deba@1421
   562
    /// Construct a new UndirGraphReader. It reads into the given graph
deba@1421
   563
    /// and it use the given reader as the default skipper.
deba@1421
   564
    UndirGraphReader(LemonReader& _reader, Graph& _graph, 
deba@1421
   565
		     const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421
   566
      : reader(_reader), own_reader(false), skipper(_skipper),
deba@1421
   567
	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421
   568
	undir_edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421
   569
			     std::string(), skipper),
deba@1421
   570
	node_reader(*reader, nodeset_reader, std::string()),
deba@1421
   571
	undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
deba@1421
   572
	attribute_reader(*reader, std::string()) {}
deba@1421
   573
deba@1421
   574
    /// \brief Destruct the graph reader.
deba@1421
   575
    ///
deba@1421
   576
    /// Destruct the graph reader.
deba@1421
   577
    ~UndirGraphReader() {
deba@1421
   578
      if (own_reader) 
deba@1421
   579
	delete reader;
deba@1421
   580
    }
deba@1421
   581
athos@1540
   582
    /// \brief Give a new node map reading command to the reader.
deba@1421
   583
    ///
athos@1540
   584
    /// Give a new node map reading command to the reader.
deba@1421
   585
    template <typename Map>
deba@1421
   586
    UndirGraphReader& readNodeMap(std::string name, Map& map) {
deba@1421
   587
      nodeset_reader.readNodeMap(name, map);
deba@1421
   588
      return *this;
deba@1421
   589
    }
deba@1421
   590
deba@1421
   591
    template <typename Map>
deba@1421
   592
    UndirGraphReader& readNodeMap(std::string name, const Map& map) {
deba@1421
   593
      nodeset_reader.readNodeMap(name, map);
deba@1421
   594
      return *this;
deba@1421
   595
    }
deba@1421
   596
athos@1540
   597
    /// \brief Give a new node map reading command to the reader.
deba@1421
   598
    ///
athos@1540
   599
    /// Give a new node map reading command to the reader.
deba@1421
   600
    template <typename Reader, typename Map>
deba@1421
   601
    UndirGraphReader& readNodeMap(std::string name, Map& map, 
deba@1421
   602
				  const Reader& reader = Reader()) {
deba@1421
   603
      nodeset_reader.readNodeMap(name, map, reader);
deba@1421
   604
      return *this;
deba@1421
   605
    }
deba@1421
   606
deba@1421
   607
    template <typename Reader, typename Map>
deba@1421
   608
    UndirGraphReader& readNodeMap(std::string name, const Map& map, 
deba@1421
   609
				  const Reader& reader = Reader()) {
deba@1421
   610
      nodeset_reader.readNodeMap(name, map, reader);
deba@1421
   611
      return *this;
deba@1421
   612
    }
deba@1421
   613
athos@1540
   614
    /// \brief Give a new node map skipping command to the reader.
deba@1421
   615
    ///
athos@1540
   616
    /// Give a new node map skipping command to the reader.
deba@1421
   617
    template <typename Reader>
deba@1421
   618
    UndirGraphReader& skipNodeMap(std::string name, 
deba@1421
   619
			     const Reader& reader = Reader()) {
deba@1421
   620
      nodeset_reader.skipNodeMap(name, reader);
deba@1421
   621
      return *this;
deba@1421
   622
    }
deba@1421
   623
athos@1540
   624
    /// \brief Give a new undirected edge map reading command to the reader.
deba@1421
   625
    ///
athos@1540
   626
    /// Give a new undirected edge map reading command to the reader.
deba@1421
   627
    template <typename Map>
deba@1421
   628
    UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) { 
deba@1421
   629
      undir_edgeset_reader.readUndirEdgeMap(name, map);
deba@1421
   630
      return *this;
deba@1421
   631
    }
deba@1421
   632
deba@1421
   633
    template <typename Map>
deba@1421
   634
    UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) { 
deba@1421
   635
      undir_edgeset_reader.readUndirEdgeMap(name, map);
deba@1421
   636
      return *this;
deba@1421
   637
    }
deba@1421
   638
deba@1421
   639
athos@1540
   640
    /// \brief Give a new undirected edge map reading command to the reader.
deba@1421
   641
    ///
athos@1540
   642
    /// Give a new undirected edge map reading command to the reader.
deba@1421
   643
    template <typename Reader, typename Map>
deba@1421
   644
    UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
deba@1421
   645
				       const Reader& reader = Reader()) {
deba@1421
   646
      undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
deba@1421
   647
      return *this;
deba@1421
   648
    }
deba@1421
   649
deba@1421
   650
    template <typename Reader, typename Map>
deba@1421
   651
    UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
deba@1421
   652
				       const Reader& reader = Reader()) {
deba@1421
   653
      undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
deba@1421
   654
      return *this;
deba@1421
   655
    }
deba@1421
   656
athos@1540
   657
    /// \brief Give a new undirected edge map skipping command to the reader.
deba@1421
   658
    ///
athos@1540
   659
    /// Give a new undirected edge map skipping command to the reader.
deba@1421
   660
    template <typename Reader>
deba@1421
   661
    UndirGraphReader& skipUndirEdgeMap(std::string name,
deba@1421
   662
				       const Reader& reader = Reader()) {
deba@1421
   663
      undir_edgeset_reader.skipUndirMap(name, reader);
deba@1421
   664
      return *this;
deba@1421
   665
    }
deba@1421
   666
deba@1421
   667
athos@1540
   668
    /// \brief Give a new edge map reading command to the reader.
deba@1421
   669
    ///
athos@1540
   670
    /// Give a new edge map reading command to the reader.
deba@1421
   671
    template <typename Map>
deba@1421
   672
    UndirGraphReader& readEdgeMap(std::string name, Map& map) { 
deba@1421
   673
      undir_edgeset_reader.readEdgeMap(name, map);
deba@1421
   674
      return *this;
deba@1421
   675
    }
deba@1421
   676
deba@1421
   677
    template <typename Map>
deba@1421
   678
    UndirGraphReader& readEdgeMap(std::string name, const Map& map) { 
deba@1421
   679
      undir_edgeset_reader.readEdgeMap(name, map);
deba@1421
   680
      return *this;
deba@1421
   681
    }
deba@1421
   682
deba@1421
   683
athos@1540
   684
    /// \brief Give a new edge map reading command to the reader.
deba@1421
   685
    ///
athos@1540
   686
    /// Give a new edge map reading command to the reader.
deba@1421
   687
    template <typename Reader, typename Map>
deba@1421
   688
    UndirGraphReader& readEdgeMap(std::string name, Map& map,
deba@1421
   689
				       const Reader& reader = Reader()) {
deba@1421
   690
      undir_edgeset_reader.readEdgeMap(name, map, reader);
deba@1421
   691
      return *this;
deba@1421
   692
    }
deba@1421
   693
deba@1421
   694
    template <typename Reader, typename Map>
deba@1421
   695
    UndirGraphReader& readEdgeMap(std::string name, const Map& map,
deba@1421
   696
				       const Reader& reader = Reader()) {
deba@1421
   697
      undir_edgeset_reader.readEdgeMap(name, map, reader);
deba@1421
   698
      return *this;
deba@1421
   699
    }
deba@1421
   700
athos@1540
   701
    /// \brief Give a new edge map skipping command to the reader.
deba@1421
   702
    ///
athos@1540
   703
    /// Give a new edge map skipping command to the reader.
deba@1421
   704
    template <typename Reader>
deba@1421
   705
    UndirGraphReader& skipEdgeMap(std::string name,
deba@1421
   706
				       const Reader& reader = Reader()) {
deba@1421
   707
      undir_edgeset_reader.skipEdgeMap(name, reader);
deba@1421
   708
      return *this;
deba@1421
   709
    }
deba@1421
   710
athos@1540
   711
    /// \brief Give a new labeled node reading command to the reader.
deba@1421
   712
    ///
athos@1540
   713
    /// Give a new labeled node reading command to the reader.
deba@1421
   714
    UndirGraphReader& readNode(std::string name, Node& node) {
deba@1421
   715
      node_reader.readNode(name, node);
deba@1421
   716
      return *this;
deba@1421
   717
    }
deba@1421
   718
athos@1540
   719
    /// \brief Give a new labeled edge reading command to the reader.
deba@1421
   720
    ///
athos@1540
   721
    /// Give a new labeled edge reading command to the reader.
deba@1429
   722
    UndirGraphReader& readEdge(std::string name, Edge& edge) {
deba@1429
   723
      undir_edge_reader.readEdge(name, edge);
deba@1429
   724
    }
deba@1429
   725
athos@1540
   726
    /// \brief Give a new labeled undirected edge reading command to the
athos@1540
   727
    /// reader.
deba@1429
   728
    ///
athos@1540
   729
    /// Give a new labeled undirected edge reading command to the reader.
deba@1421
   730
    UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
deba@1421
   731
      undir_edge_reader.readUndirEdge(name, edge);
deba@1421
   732
    }
deba@1421
   733
athos@1540
   734
    /// \brief Give a new attribute reading command.
deba@1421
   735
    ///
athos@1540
   736
    ///  Give a new attribute reading command.
deba@1421
   737
    template <typename Value>
deba@1421
   738
    UndirGraphReader& readAttribute(std::string name, Value& value) {
deba@1421
   739
      attribute_reader.readAttribute(name, value);
deba@1421
   740
      return *this;
deba@1421
   741
    }
deba@1421
   742
    
athos@1540
   743
    /// \brief Give a new attribute reading command.
deba@1421
   744
    ///
athos@1540
   745
    ///  Give a new attribute reading command.
deba@1421
   746
    template <typename Reader, typename Value>
deba@1421
   747
    UndirGraphReader& readAttribute(std::string name, Value& value, 
deba@1421
   748
			       const Reader& reader) {
deba@1421
   749
      attribute_reader.readAttribute<Reader>(name, value, reader);
deba@1421
   750
      return *this;
deba@1421
   751
    }
deba@1421
   752
deba@1421
   753
    /// \brief Conversion operator to LemonReader.
deba@1421
   754
    ///
deba@1421
   755
    /// Conversion operator to LemonReader. It make possible
deba@1421
   756
    /// to access the encapsulated \e LemonReader, this way
deba@1421
   757
    /// you can attach to this reader new instances of 
deba@1421
   758
    /// \e LemonReader::SectionReader.
deba@1421
   759
    operator LemonReader&() {
deba@1421
   760
      return *reader;
deba@1421
   761
    }
deba@1421
   762
athos@1540
   763
    /// \brief Executes the reading commands.
deba@1421
   764
    ///
athos@1540
   765
    /// Executes the reading commands.
deba@1421
   766
    void run() {
deba@1421
   767
      reader->run();
deba@1421
   768
    }
deba@1421
   769
deba@1429
   770
    /// \brief Gives back the node by its id.
deba@1429
   771
    ///
deba@1429
   772
    /// It reads an id from the stream and gives back which node belongs to
deba@1429
   773
    /// it. It is possible only if there was read an "id" named node map.
deba@1429
   774
    Node readId(std::istream& is, Node) const {
deba@1429
   775
      return nodeset_reader.readId(is, Node());
deba@1429
   776
    } 
deba@1429
   777
deba@1429
   778
    /// \brief Gives back the edge by its id.
deba@1429
   779
    ///
deba@1429
   780
    /// It reads an id from the stream and gives back which edge belongs to
deba@1429
   781
    /// it. It is possible only if there was read an "id" named edge map.
deba@1429
   782
    Edge readId(std::istream& is, Edge) const {
deba@1429
   783
      return undir_edgeset_reader.readId(is, Edge());
deba@1429
   784
    } 
deba@1429
   785
deba@1429
   786
    /// \brief Gives back the undirected edge by its id.
deba@1429
   787
    ///
deba@1429
   788
    /// It reads an id from the stream and gives back which undirected edge 
deba@1429
   789
    /// belongs to it. It is possible only if there was read an "id" named 
deba@1429
   790
    /// edge map.
deba@1429
   791
    UndirEdge readId(std::istream& is, UndirEdge) const {
deba@1429
   792
      return undir_edgeset_reader.readId(is, UndirEdge());
deba@1429
   793
    } 
deba@1429
   794
    
deba@1429
   795
deba@1421
   796
  private:
deba@1421
   797
deba@1421
   798
    LemonReader* reader;
deba@1421
   799
    bool own_reader;
deba@1421
   800
deba@1421
   801
    DefaultSkipper skipper;
deba@1421
   802
deba@1421
   803
    NodeSetReader<Graph, ReaderTraits> nodeset_reader;
deba@1421
   804
    UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
deba@1421
   805
deba@1421
   806
    NodeReader<Graph> node_reader;
deba@1421
   807
    UndirEdgeReader<Graph> undir_edge_reader;
deba@1421
   808
    
deba@1421
   809
    AttributeReader<ReaderTraits> attribute_reader;
deba@1421
   810
  };
deba@1421
   811
athos@1534
   812
  /// \brief Read an undirected graph from an input stream.
deba@1421
   813
  ///
athos@1534
   814
  /// Read an undirected graph from an input stream.
athos@1534
   815
  /// \param is The input stream.
athos@1534
   816
  /// \param g The graph.
athos@1534
   817
  template<typename Graph>
athos@1534
   818
  void readUndirGraph(std::istream& is, Graph &g) {
athos@1534
   819
    UndirGraphReader<Graph> reader(is, g);
athos@1534
   820
    reader.run();
athos@1534
   821
  }
athos@1534
   822
athos@1534
   823
  /// \brief Read an undirected multigraph (undirected graph + capacity
athos@1534
   824
  /// map on the edges) from an input stream.
athos@1534
   825
  ///
athos@1534
   826
  /// Read an undirected multigraph (undirected graph + capacity
athos@1534
   827
  /// map on the edges) from an input stream.
deba@1421
   828
  /// \param is The input stream.
deba@1421
   829
  /// \param g The graph.
deba@1421
   830
  /// \param capacity The capacity map.
deba@1421
   831
  template<typename Graph, typename CapacityMap>
deba@1421
   832
  void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
deba@1421
   833
    UndirGraphReader<Graph> reader(is, g);
deba@1421
   834
    reader.readUndirEdgeMap("capacity", capacity);
deba@1421
   835
    reader.run();
deba@1421
   836
  }
deba@1421
   837
deba@1421
   838
deba@1333
   839
  /// @}
deba@1137
   840
}
deba@1214
   841
deba@1214
   842
#endif