lemon/graph_reader.h
author hegyi
Mon, 21 Nov 2005 18:03:20 +0000
changeset 1823 cb082cdf3667
parent 1705 3f63d9db307b
child 1875 98698b69a902
permissions -rw-r--r--
NewMapWin has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.
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@1705
   125
    GraphReader(std::istream& _is, Graph& _graph, 
deba@1408
   126
		const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421
   127
      : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
deba@1421
   128
	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421
   129
	edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421
   130
		       std::string(), skipper),
deba@1408
   131
	node_reader(*reader, nodeset_reader, std::string()),
deba@1408
   132
	edge_reader(*reader, edgeset_reader, std::string()),
deba@1408
   133
	attribute_reader(*reader, std::string()) {}
deba@1408
   134
deba@1408
   135
    /// \brief Construct a new GraphReader.
deba@1408
   136
    ///
deba@1408
   137
    /// Construct a new GraphReader. It reads into the given graph
athos@1540
   138
    /// and it uses the given reader as the default skipper.
deba@1705
   139
    GraphReader(const std::string& _filename, Graph& _graph, 
deba@1408
   140
		const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1408
   141
      : reader(new LemonReader(_filename)), own_reader(true), 
deba@1421
   142
	skipper(_skipper),
deba@1421
   143
	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421
   144
	edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421
   145
		       std::string(), skipper),
deba@1408
   146
	node_reader(*reader, nodeset_reader, std::string()),
deba@1408
   147
	edge_reader(*reader, edgeset_reader, std::string()),
deba@1408
   148
	attribute_reader(*reader, std::string()) {}
deba@1408
   149
deba@1408
   150
    /// \brief Construct a new GraphReader.
deba@1408
   151
    ///
deba@1408
   152
    /// Construct a new GraphReader. It reads into the given graph
athos@1540
   153
    /// and it uses the given reader as the default skipper.
deba@1705
   154
    GraphReader(LemonReader& _reader, Graph& _graph, 
deba@1408
   155
		const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421
   156
      : reader(_reader), own_reader(false), skipper(_skipper),
deba@1421
   157
	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421
   158
	edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421
   159
		       std::string(), skipper),
deba@1408
   160
	node_reader(*reader, nodeset_reader, std::string()),
deba@1408
   161
	edge_reader(*reader, edgeset_reader, std::string()),
deba@1408
   162
	attribute_reader(*reader, std::string()) {}
deba@1137
   163
deba@1137
   164
    /// \brief Destruct the graph reader.
deba@1137
   165
    ///
deba@1137
   166
    /// Destruct the graph reader.
deba@1137
   167
    ~GraphReader() {
deba@1408
   168
      if (own_reader) 
deba@1408
   169
	delete reader;
deba@1137
   170
    }
deba@1137
   171
athos@1540
   172
    /// \brief Give a new node map reading command to the reader.
deba@1137
   173
    ///
athos@1540
   174
    /// Give a new node map reading command to the reader.
deba@1137
   175
    template <typename Map>
deba@1394
   176
    GraphReader& readNodeMap(std::string name, Map& map) {
deba@1421
   177
      nodeset_reader.readNodeMap(name, map);
deba@1421
   178
      return *this;
deba@1421
   179
    }
deba@1421
   180
deba@1421
   181
    template <typename Map>
deba@1421
   182
    GraphReader& readNodeMap(std::string name, const Map& map) {
deba@1421
   183
      nodeset_reader.readNodeMap(name, map);
deba@1408
   184
      return *this;
deba@1137
   185
    }
deba@1137
   186
athos@1540
   187
    /// \brief Give a new node map reading command to the reader.
deba@1137
   188
    ///
athos@1540
   189
    /// Give a new node map reading command to the reader.
deba@1137
   190
    template <typename Reader, typename Map>
deba@1394
   191
    GraphReader& readNodeMap(std::string name, Map& map, 
deba@1137
   192
			     const Reader& reader = Reader()) {
deba@1421
   193
      nodeset_reader.readNodeMap(name, map, reader);
deba@1421
   194
      return *this;
deba@1421
   195
    }
deba@1421
   196
deba@1421
   197
    template <typename Reader, typename Map>
deba@1421
   198
    GraphReader& readNodeMap(std::string name, const Map& map, 
deba@1421
   199
			     const Reader& reader = Reader()) {
deba@1421
   200
      nodeset_reader.readNodeMap(name, map, reader);
deba@1137
   201
      return *this;
deba@1137
   202
    }
deba@1137
   203
athos@1540
   204
    /// \brief Give a new node map skipping command to the reader.
deba@1137
   205
    ///
athos@1540
   206
    /// Give a new node map skipping command to the reader.
deba@1137
   207
    template <typename Reader>
deba@1137
   208
    GraphReader& skipNodeMap(std::string name, 
deba@1137
   209
			     const Reader& reader = Reader()) {
deba@1421
   210
      nodeset_reader.skipNodeMap(name, reader);
deba@1137
   211
      return *this;
deba@1137
   212
    }
deba@1137
   213
athos@1540
   214
    /// \brief Give a new edge map reading command to the reader.
deba@1137
   215
    ///
athos@1540
   216
    /// Give a new edge map reading command to the reader.
deba@1137
   217
    template <typename Map>
deba@1394
   218
    GraphReader& readEdgeMap(std::string name, Map& map) { 
deba@1421
   219
      edgeset_reader.readEdgeMap(name, map);
deba@1421
   220
      return *this;
deba@1421
   221
    }
deba@1421
   222
deba@1421
   223
    template <typename Map>
deba@1421
   224
    GraphReader& readEdgeMap(std::string name, const Map& map) { 
deba@1421
   225
      edgeset_reader.readEdgeMap(name, map);
deba@1408
   226
      return *this;
deba@1137
   227
    }
deba@1137
   228
deba@1137
   229
athos@1540
   230
    /// \brief Give a new edge map reading command to the reader.
deba@1137
   231
    ///
athos@1540
   232
    /// Give a new edge map reading command to the reader.
deba@1137
   233
    template <typename Reader, typename Map>
deba@1394
   234
    GraphReader& readEdgeMap(std::string name, Map& map,
deba@1137
   235
			     const Reader& reader = Reader()) {
deba@1421
   236
      edgeset_reader.readEdgeMap(name, map, reader);
deba@1421
   237
      return *this;
deba@1421
   238
    }
deba@1421
   239
deba@1421
   240
    template <typename Reader, typename Map>
deba@1421
   241
    GraphReader& readEdgeMap(std::string name, const Map& map,
deba@1421
   242
			     const Reader& reader = Reader()) {
deba@1421
   243
      edgeset_reader.readEdgeMap(name, map, reader);
deba@1137
   244
      return *this;
deba@1137
   245
    }
deba@1137
   246
athos@1540
   247
    /// \brief Give a new edge map skipping command to the reader.
deba@1137
   248
    ///
athos@1540
   249
    /// Give a new edge map skipping command to the reader.
deba@1137
   250
    template <typename Reader>
deba@1421
   251
    GraphReader& skipEdgeMap(std::string name, 
deba@1137
   252
			     const Reader& reader = Reader()) {
deba@1421
   253
      edgeset_reader.skipEdgeMap(name, reader);
deba@1137
   254
      return *this;
deba@1137
   255
    }
deba@1137
   256
athos@1540
   257
    /// \brief Give a new labeled node reading command to the reader.
deba@1137
   258
    ///
athos@1540
   259
    /// Give a new labeled node reading command to the reader.
deba@1394
   260
    GraphReader& readNode(std::string name, Node& node) {
deba@1408
   261
      node_reader.readNode(name, node);
deba@1137
   262
      return *this;
deba@1137
   263
    }
deba@1137
   264
athos@1540
   265
    /// \brief Give a new labeled edge reading command to the reader.
deba@1137
   266
    ///
athos@1540
   267
    /// Give a new labeled edge reading command to the reader.
deba@1394
   268
    GraphReader& readEdge(std::string name, Edge& edge) {
deba@1408
   269
      edge_reader.readEdge(name, edge);
deba@1476
   270
      return *this;
deba@1408
   271
    }
deba@1408
   272
athos@1540
   273
    /// \brief Give a new attribute reading command.
deba@1408
   274
    ///
athos@1540
   275
    ///  Give a new attribute reading command.
deba@1408
   276
    template <typename Value>
deba@1408
   277
    GraphReader& readAttribute(std::string name, Value& value) {
deba@1408
   278
      attribute_reader.readAttribute(name, value);
deba@1137
   279
      return *this;
deba@1137
   280
    }
deba@1408
   281
    
athos@1540
   282
    /// \brief Give a new attribute reading command.
deba@1408
   283
    ///
athos@1540
   284
    ///  Give a new attribute reading command.
deba@1408
   285
    template <typename Reader, typename Value>
deba@1408
   286
    GraphReader& readAttribute(std::string name, Value& value, 
deba@1408
   287
			       const Reader& reader) {
deba@1408
   288
      attribute_reader.readAttribute<Reader>(name, value, reader);
deba@1408
   289
      return *this;
deba@1408
   290
    }
deba@1408
   291
deba@1408
   292
    /// \brief Conversion operator to LemonReader.
deba@1408
   293
    ///
athos@1540
   294
    /// Conversion operator to LemonReader. It makes possible to access the
athos@1540
   295
    /// encapsulated \e LemonReader, this way you can attach to this reader
athos@1540
   296
    /// new instances of \e LemonReader::SectionReader. For more details see
athos@1540
   297
    /// the \ref rwbackground "Background of Reading and Writing".
deba@1408
   298
    operator LemonReader&() {
deba@1408
   299
      return *reader;
deba@1408
   300
    }
deba@1137
   301
athos@1540
   302
    /// \brief Executes the reading commands.
deba@1137
   303
    ///
athos@1540
   304
    /// Executes the reading commands.
deba@1137
   305
    void run() {
deba@1408
   306
      reader->run();
deba@1396
   307
    }
deba@1396
   308
deba@1429
   309
    /// \brief Gives back the node by its id.
deba@1429
   310
    ///
deba@1429
   311
    /// It reads an id from the stream and gives back which node belongs to
deba@1429
   312
    /// it. It is possible only if there was read an "id" named node map.
deba@1429
   313
    Node readId(std::istream& is, Node) const {
deba@1429
   314
      return nodeset_reader.readId(is, Node());
deba@1429
   315
    } 
deba@1429
   316
deba@1429
   317
    /// \brief Gives back the edge by its id.
deba@1429
   318
    ///
deba@1429
   319
    /// It reads an id from the stream and gives back which edge belongs to
deba@1429
   320
    /// it. It is possible only if there was read an "id" named edge map.
deba@1429
   321
    Edge readId(std::istream& is, Edge) const {
deba@1429
   322
      return edgeset_reader.readId(is, Edge());
deba@1429
   323
    } 
deba@1429
   324
deba@1137
   325
  private:
deba@1137
   326
deba@1408
   327
    LemonReader* reader;
deba@1408
   328
    bool own_reader;
deba@1137
   329
deba@1408
   330
    DefaultSkipper skipper;
deba@1137
   331
deba@1408
   332
    NodeSetReader<Graph, ReaderTraits> nodeset_reader;
deba@1408
   333
    EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
deba@1408
   334
deba@1408
   335
    NodeReader<Graph> node_reader;
deba@1408
   336
    EdgeReader<Graph> edge_reader;
deba@1408
   337
    
deba@1408
   338
    AttributeReader<ReaderTraits> attribute_reader;
deba@1137
   339
  };
deba@1137
   340
athos@1534
   341
deba@1744
   342
  /// \brief Read a graph from the input.
deba@1333
   343
  ///
deba@1744
   344
  /// It is a helper function to read a graph from the given input
deba@1744
   345
  /// stream. It gives back an GraphReader object and this object
deba@1744
   346
  /// can read more maps, labeled nodes, edges and attributes.
athos@1534
   347
  ///
deba@1744
   348
  /// \warning Do not forget to call the \c run() function.
deba@1744
   349
  ///
athos@1534
   350
  /// \param is The input stream.
athos@1534
   351
  /// \param g The graph.
athos@1534
   352
  template<typename Graph>
deba@1744
   353
  GraphReader<Graph> graphReader(std::istream& is, Graph &g) {
deba@1744
   354
    return GraphReader<Graph>(is, g);
athos@1534
   355
  }
athos@1534
   356
deba@1744
   357
  /// \brief Read a graph from the input.
deba@1744
   358
  ///
deba@1744
   359
  /// It is a helper function to read a graph from the given input
deba@1744
   360
  /// file. It gives back an GraphReader object and this object
deba@1744
   361
  /// can read more maps, labeled nodes, edges and attributes.
deba@1744
   362
  ///
deba@1744
   363
  /// \warning Do not forget to call the \c run() function.
deba@1744
   364
  ///
deba@1744
   365
  /// \param fn The input filename.
athos@1534
   366
  /// \param g The graph.
deba@1744
   367
  template<typename Graph>
deba@1744
   368
  GraphReader<Graph> graphReader(const std::string& fn, Graph &g) {
deba@1744
   369
    return GraphReader<Graph>(fn, g);
athos@1534
   370
  }
athos@1534
   371
deba@1744
   372
  /// \brief The undirected graph reader class.
deba@1421
   373
  ///
athos@1540
   374
  /// The \c UndirGraphReader class provides the graph input. 
athos@1540
   375
  /// Before you read this documentation it might be useful to read the general
athos@1540
   376
  /// description of  \ref graph-io-page "Graph Input-Output".
athos@1540
   377
  ///
athos@1540
   378
  /// If you don't need very sophisticated
athos@1540
   379
  /// behaviour then you can use the versions of the public function
athos@1540
   380
  /// \ref readGraph() to read a graph (or a max flow instance etc).
athos@1540
   381
  ///
deba@1421
   382
  /// The given file format may contain several maps and labeled nodes or 
deba@1421
   383
  /// edges.
deba@1421
   384
  ///
deba@1421
   385
  /// If you read a graph you need not read all the maps and items just those
athos@1540
   386
  /// that you need. The interface of the \c UndirGraphReader is very similar
athos@1540
   387
  /// to the UndirGraphWriter but the reading method does not depend on the
athos@1540
   388
  /// order of the given commands.
deba@1421
   389
  ///
deba@1421
   390
  /// The reader object suppose that each not readed value does not contain 
deba@1421
   391
  /// whitespaces, therefore it has some extra possibilities to control how
deba@1421
   392
  /// it should skip the values when the string representation contains spaces.
deba@1421
   393
  ///
deba@1421
   394
  /// \code
deba@1421
   395
  /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
deba@1421
   396
  /// \endcode
deba@1421
   397
  ///
deba@1421
   398
  /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
deba@1421
   399
  /// If there is a map that you do not want to read from the file and there is
deba@1421
   400
  /// whitespace in the string represenation of the values then you should
deba@1421
   401
  /// call the \c skipNodeMap() template member function with proper 
deba@1421
   402
  /// parameters.
deba@1421
   403
  ///
deba@1421
   404
  /// \code
deba@1421
   405
  /// reader.readNodeMap("coords", coords);
deba@1421
   406
  ///
deba@1421
   407
  /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
deba@1421
   408
  /// reader.skipNodeMap<QuotedStringReader>("description");
deba@1421
   409
  ///
deba@1421
   410
  /// reader.readNodeMap("color", colorMap);
deba@1421
   411
  /// \endcode
deba@1421
   412
  ///
deba@1421
   413
  /// With the \c readUndirEdgeMap() member function you can give an 
deba@1421
   414
  /// undir edge map reading command similar to the NodeMaps. 
deba@1421
   415
  ///
deba@1421
   416
  /// \code
deba@1421
   417
  /// reader.readUndirEdgeMap("capacity", capacityMap);
deba@1421
   418
  /// \endcode
deba@1421
   419
  ///
deba@1421
   420
  /// The reading of the directed edge maps is just a syntactical sugar.
deba@1421
   421
  /// It reads two undirected edgemaps into a directed edge map. The 
deba@1421
   422
  /// undirected edge maps' name should be start with the \c '+' and the
deba@1421
   423
  /// \c '-' character and the same.
deba@1421
   424
  ///
deba@1421
   425
  /// \code
deba@1421
   426
  /// reader.readEdgeMap("flow", flowMap);
deba@1421
   427
  /// \endcode 
deba@1421
   428
  ///
deba@1421
   429
  /// With \c readNode() and \c readUndirEdge() functions you can read 
deba@1421
   430
  /// labeled Nodes and UndirEdges.
deba@1421
   431
  ///
deba@1421
   432
  /// \code
deba@1421
   433
  /// reader.readNode("source", sourceNode);
deba@1421
   434
  /// reader.readNode("target", targetNode);
deba@1421
   435
  ///
deba@1421
   436
  /// reader.readUndirEdge("observed", undirEdge);
deba@1421
   437
  /// \endcode
deba@1421
   438
  ///
deba@1421
   439
  /// With the \c readAttribute() functions you can read an attribute
deba@1421
   440
  /// in a variable. You can specify the reader for the attribute as
deba@1421
   441
  /// the nodemaps.
deba@1421
   442
  ///
deba@1421
   443
  /// After you give all read commands you must call the \c run() member
deba@1421
   444
  /// function, which execute all the commands.
deba@1421
   445
  ///
deba@1421
   446
  /// \code
deba@1421
   447
  /// reader.run();
deba@1421
   448
  /// \endcode
deba@1421
   449
  ///
deba@1421
   450
  /// \see GraphReader
deba@1421
   451
  /// \see DefaultReaderTraits
deba@1421
   452
  /// \see \ref UndirGraphWriter
deba@1421
   453
  /// \see \ref graph-io-page
deba@1421
   454
  ///
deba@1421
   455
  /// \author Balazs Dezso
deba@1421
   456
  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
deba@1421
   457
  class UndirGraphReader {
deba@1421
   458
  public:
deba@1421
   459
    
deba@1421
   460
    typedef _Graph Graph;
deba@1421
   461
    typedef typename Graph::Node Node;
deba@1421
   462
    typedef typename Graph::Edge Edge;
deba@1421
   463
    typedef typename Graph::UndirEdge UndirEdge;
deba@1421
   464
deba@1421
   465
    typedef _ReaderTraits ReaderTraits;
deba@1421
   466
    typedef typename ReaderTraits::Skipper DefaultSkipper;
deba@1421
   467
deba@1421
   468
    /// \brief Construct a new UndirGraphReader.
deba@1421
   469
    ///
deba@1421
   470
    /// Construct a new UndirGraphReader. It reads into the given graph
deba@1421
   471
    /// and it use the given reader as the default skipper.
deba@1421
   472
    UndirGraphReader(std::istream& _is, Graph& _graph, 
deba@1421
   473
		     const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421
   474
      : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
deba@1421
   475
	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421
   476
	undir_edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421
   477
			     std::string(), skipper),
deba@1421
   478
	node_reader(*reader, nodeset_reader, std::string()),
deba@1421
   479
	undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
deba@1421
   480
	attribute_reader(*reader, std::string()) {}
deba@1421
   481
deba@1421
   482
    /// \brief Construct a new UndirGraphReader.
deba@1421
   483
    ///
deba@1421
   484
    /// Construct a new UndirGraphReader. It reads into the given graph
deba@1421
   485
    /// and it use the given reader as the default skipper.
deba@1421
   486
    UndirGraphReader(const std::string& _filename, Graph& _graph, 
deba@1421
   487
		     const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421
   488
      : reader(new LemonReader(_filename)), own_reader(true), 
deba@1421
   489
	skipper(_skipper),
deba@1421
   490
	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421
   491
	undir_edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421
   492
			     std::string(), skipper),
deba@1421
   493
	node_reader(*reader, nodeset_reader, std::string()),
deba@1421
   494
	undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
deba@1421
   495
	attribute_reader(*reader, std::string()) {}
deba@1421
   496
deba@1421
   497
    /// \brief Construct a new UndirGraphReader.
deba@1421
   498
    ///
deba@1421
   499
    /// Construct a new UndirGraphReader. It reads into the given graph
deba@1421
   500
    /// and it use the given reader as the default skipper.
deba@1421
   501
    UndirGraphReader(LemonReader& _reader, Graph& _graph, 
deba@1421
   502
		     const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421
   503
      : reader(_reader), own_reader(false), skipper(_skipper),
deba@1421
   504
	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421
   505
	undir_edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421
   506
			     std::string(), skipper),
deba@1421
   507
	node_reader(*reader, nodeset_reader, std::string()),
deba@1421
   508
	undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
deba@1421
   509
	attribute_reader(*reader, std::string()) {}
deba@1421
   510
deba@1421
   511
    /// \brief Destruct the graph reader.
deba@1421
   512
    ///
deba@1421
   513
    /// Destruct the graph reader.
deba@1421
   514
    ~UndirGraphReader() {
deba@1421
   515
      if (own_reader) 
deba@1421
   516
	delete reader;
deba@1421
   517
    }
deba@1421
   518
athos@1540
   519
    /// \brief Give a new node map reading command to the reader.
deba@1421
   520
    ///
athos@1540
   521
    /// Give a new node map reading command to the reader.
deba@1421
   522
    template <typename Map>
deba@1421
   523
    UndirGraphReader& readNodeMap(std::string name, Map& map) {
deba@1421
   524
      nodeset_reader.readNodeMap(name, map);
deba@1421
   525
      return *this;
deba@1421
   526
    }
deba@1421
   527
deba@1421
   528
    template <typename Map>
deba@1421
   529
    UndirGraphReader& readNodeMap(std::string name, const Map& map) {
deba@1421
   530
      nodeset_reader.readNodeMap(name, map);
deba@1421
   531
      return *this;
deba@1421
   532
    }
deba@1421
   533
athos@1540
   534
    /// \brief Give a new node map reading command to the reader.
deba@1421
   535
    ///
athos@1540
   536
    /// Give a new node map reading command to the reader.
deba@1421
   537
    template <typename Reader, typename Map>
deba@1421
   538
    UndirGraphReader& readNodeMap(std::string name, Map& map, 
deba@1421
   539
				  const Reader& reader = Reader()) {
deba@1421
   540
      nodeset_reader.readNodeMap(name, map, reader);
deba@1421
   541
      return *this;
deba@1421
   542
    }
deba@1421
   543
deba@1421
   544
    template <typename Reader, typename Map>
deba@1421
   545
    UndirGraphReader& readNodeMap(std::string name, const Map& map, 
deba@1421
   546
				  const Reader& reader = Reader()) {
deba@1421
   547
      nodeset_reader.readNodeMap(name, map, reader);
deba@1421
   548
      return *this;
deba@1421
   549
    }
deba@1421
   550
athos@1540
   551
    /// \brief Give a new node map skipping command to the reader.
deba@1421
   552
    ///
athos@1540
   553
    /// Give a new node map skipping command to the reader.
deba@1421
   554
    template <typename Reader>
deba@1421
   555
    UndirGraphReader& skipNodeMap(std::string name, 
deba@1421
   556
			     const Reader& reader = Reader()) {
deba@1421
   557
      nodeset_reader.skipNodeMap(name, reader);
deba@1421
   558
      return *this;
deba@1421
   559
    }
deba@1421
   560
athos@1540
   561
    /// \brief Give a new undirected edge map reading command to the reader.
deba@1421
   562
    ///
athos@1540
   563
    /// Give a new undirected edge map reading command to the reader.
deba@1421
   564
    template <typename Map>
deba@1421
   565
    UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) { 
deba@1421
   566
      undir_edgeset_reader.readUndirEdgeMap(name, map);
deba@1421
   567
      return *this;
deba@1421
   568
    }
deba@1421
   569
deba@1421
   570
    template <typename Map>
deba@1421
   571
    UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) { 
deba@1421
   572
      undir_edgeset_reader.readUndirEdgeMap(name, map);
deba@1421
   573
      return *this;
deba@1421
   574
    }
deba@1421
   575
deba@1421
   576
athos@1540
   577
    /// \brief Give a new undirected edge map reading command to the reader.
deba@1421
   578
    ///
athos@1540
   579
    /// Give a new undirected edge map reading command to the reader.
deba@1421
   580
    template <typename Reader, typename Map>
deba@1421
   581
    UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
deba@1421
   582
				       const Reader& reader = Reader()) {
deba@1421
   583
      undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
deba@1421
   584
      return *this;
deba@1421
   585
    }
deba@1421
   586
deba@1421
   587
    template <typename Reader, typename Map>
deba@1421
   588
    UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
deba@1421
   589
				       const Reader& reader = Reader()) {
deba@1421
   590
      undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
deba@1421
   591
      return *this;
deba@1421
   592
    }
deba@1421
   593
athos@1540
   594
    /// \brief Give a new undirected edge map skipping command to the reader.
deba@1421
   595
    ///
athos@1540
   596
    /// Give a new undirected edge map skipping command to the reader.
deba@1421
   597
    template <typename Reader>
deba@1421
   598
    UndirGraphReader& skipUndirEdgeMap(std::string name,
deba@1421
   599
				       const Reader& reader = Reader()) {
deba@1421
   600
      undir_edgeset_reader.skipUndirMap(name, reader);
deba@1421
   601
      return *this;
deba@1421
   602
    }
deba@1421
   603
deba@1421
   604
athos@1540
   605
    /// \brief Give a new edge map reading command to the reader.
deba@1421
   606
    ///
athos@1540
   607
    /// Give a new edge map reading command to the reader.
deba@1421
   608
    template <typename Map>
deba@1421
   609
    UndirGraphReader& readEdgeMap(std::string name, Map& map) { 
deba@1421
   610
      undir_edgeset_reader.readEdgeMap(name, map);
deba@1421
   611
      return *this;
deba@1421
   612
    }
deba@1421
   613
deba@1421
   614
    template <typename Map>
deba@1421
   615
    UndirGraphReader& readEdgeMap(std::string name, const Map& map) { 
deba@1421
   616
      undir_edgeset_reader.readEdgeMap(name, map);
deba@1421
   617
      return *this;
deba@1421
   618
    }
deba@1421
   619
deba@1421
   620
athos@1540
   621
    /// \brief Give a new edge map reading command to the reader.
deba@1421
   622
    ///
athos@1540
   623
    /// Give a new edge map reading command to the reader.
deba@1421
   624
    template <typename Reader, typename Map>
deba@1421
   625
    UndirGraphReader& readEdgeMap(std::string name, Map& map,
deba@1421
   626
				       const Reader& reader = Reader()) {
deba@1421
   627
      undir_edgeset_reader.readEdgeMap(name, map, reader);
deba@1421
   628
      return *this;
deba@1421
   629
    }
deba@1421
   630
deba@1421
   631
    template <typename Reader, typename Map>
deba@1421
   632
    UndirGraphReader& readEdgeMap(std::string name, const Map& map,
deba@1421
   633
				       const Reader& reader = Reader()) {
deba@1421
   634
      undir_edgeset_reader.readEdgeMap(name, map, reader);
deba@1421
   635
      return *this;
deba@1421
   636
    }
deba@1421
   637
athos@1540
   638
    /// \brief Give a new edge map skipping command to the reader.
deba@1421
   639
    ///
athos@1540
   640
    /// Give a new edge map skipping command to the reader.
deba@1421
   641
    template <typename Reader>
deba@1421
   642
    UndirGraphReader& skipEdgeMap(std::string name,
deba@1421
   643
				       const Reader& reader = Reader()) {
deba@1421
   644
      undir_edgeset_reader.skipEdgeMap(name, reader);
deba@1421
   645
      return *this;
deba@1421
   646
    }
deba@1421
   647
athos@1540
   648
    /// \brief Give a new labeled node reading command to the reader.
deba@1421
   649
    ///
athos@1540
   650
    /// Give a new labeled node reading command to the reader.
deba@1421
   651
    UndirGraphReader& readNode(std::string name, Node& node) {
deba@1421
   652
      node_reader.readNode(name, node);
deba@1421
   653
      return *this;
deba@1421
   654
    }
deba@1421
   655
athos@1540
   656
    /// \brief Give a new labeled edge reading command to the reader.
deba@1421
   657
    ///
athos@1540
   658
    /// Give a new labeled edge reading command to the reader.
deba@1429
   659
    UndirGraphReader& readEdge(std::string name, Edge& edge) {
deba@1429
   660
      undir_edge_reader.readEdge(name, edge);
deba@1429
   661
    }
deba@1429
   662
athos@1540
   663
    /// \brief Give a new labeled undirected edge reading command to the
athos@1540
   664
    /// reader.
deba@1429
   665
    ///
athos@1540
   666
    /// Give a new labeled undirected edge reading command to the reader.
deba@1421
   667
    UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
deba@1421
   668
      undir_edge_reader.readUndirEdge(name, edge);
deba@1421
   669
    }
deba@1421
   670
athos@1540
   671
    /// \brief Give a new attribute reading command.
deba@1421
   672
    ///
athos@1540
   673
    ///  Give a new attribute reading command.
deba@1421
   674
    template <typename Value>
deba@1421
   675
    UndirGraphReader& readAttribute(std::string name, Value& value) {
deba@1421
   676
      attribute_reader.readAttribute(name, value);
deba@1421
   677
      return *this;
deba@1421
   678
    }
deba@1421
   679
    
athos@1540
   680
    /// \brief Give a new attribute reading command.
deba@1421
   681
    ///
athos@1540
   682
    ///  Give a new attribute reading command.
deba@1421
   683
    template <typename Reader, typename Value>
deba@1421
   684
    UndirGraphReader& readAttribute(std::string name, Value& value, 
deba@1421
   685
			       const Reader& reader) {
deba@1421
   686
      attribute_reader.readAttribute<Reader>(name, value, reader);
deba@1421
   687
      return *this;
deba@1421
   688
    }
deba@1421
   689
deba@1421
   690
    /// \brief Conversion operator to LemonReader.
deba@1421
   691
    ///
deba@1421
   692
    /// Conversion operator to LemonReader. It make possible
deba@1421
   693
    /// to access the encapsulated \e LemonReader, this way
deba@1421
   694
    /// you can attach to this reader new instances of 
deba@1421
   695
    /// \e LemonReader::SectionReader.
deba@1421
   696
    operator LemonReader&() {
deba@1421
   697
      return *reader;
deba@1421
   698
    }
deba@1421
   699
athos@1540
   700
    /// \brief Executes the reading commands.
deba@1421
   701
    ///
athos@1540
   702
    /// Executes the reading commands.
deba@1421
   703
    void run() {
deba@1421
   704
      reader->run();
deba@1421
   705
    }
deba@1421
   706
deba@1429
   707
    /// \brief Gives back the node by its id.
deba@1429
   708
    ///
deba@1429
   709
    /// It reads an id from the stream and gives back which node belongs to
deba@1429
   710
    /// it. It is possible only if there was read an "id" named node map.
deba@1429
   711
    Node readId(std::istream& is, Node) const {
deba@1429
   712
      return nodeset_reader.readId(is, Node());
deba@1429
   713
    } 
deba@1429
   714
deba@1429
   715
    /// \brief Gives back the edge by its id.
deba@1429
   716
    ///
deba@1429
   717
    /// It reads an id from the stream and gives back which edge belongs to
deba@1429
   718
    /// it. It is possible only if there was read an "id" named edge map.
deba@1429
   719
    Edge readId(std::istream& is, Edge) const {
deba@1429
   720
      return undir_edgeset_reader.readId(is, Edge());
deba@1429
   721
    } 
deba@1429
   722
deba@1429
   723
    /// \brief Gives back the undirected edge by its id.
deba@1429
   724
    ///
deba@1429
   725
    /// It reads an id from the stream and gives back which undirected edge 
deba@1429
   726
    /// belongs to it. It is possible only if there was read an "id" named 
deba@1429
   727
    /// edge map.
deba@1429
   728
    UndirEdge readId(std::istream& is, UndirEdge) const {
deba@1429
   729
      return undir_edgeset_reader.readId(is, UndirEdge());
deba@1429
   730
    } 
deba@1429
   731
    
deba@1429
   732
deba@1421
   733
  private:
deba@1421
   734
deba@1421
   735
    LemonReader* reader;
deba@1421
   736
    bool own_reader;
deba@1421
   737
deba@1421
   738
    DefaultSkipper skipper;
deba@1421
   739
deba@1421
   740
    NodeSetReader<Graph, ReaderTraits> nodeset_reader;
deba@1421
   741
    UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
deba@1421
   742
deba@1421
   743
    NodeReader<Graph> node_reader;
deba@1421
   744
    UndirEdgeReader<Graph> undir_edge_reader;
deba@1421
   745
    
deba@1421
   746
    AttributeReader<ReaderTraits> attribute_reader;
deba@1421
   747
  };
deba@1421
   748
deba@1744
   749
  /// \brief Read an undirected graph from the input.
deba@1421
   750
  ///
deba@1744
   751
  /// It is a helper function to read an undirected graph from the given input
deba@1744
   752
  /// stream. It gives back an UndirGraphReader object and this object
deba@1744
   753
  /// can read more maps, labeled nodes, edges, undirected edges and
deba@1744
   754
  /// attributes.
deba@1744
   755
  ///
deba@1744
   756
  /// \warning Do not forget to call the \c run() function.
deba@1744
   757
  ///
athos@1534
   758
  /// \param is The input stream.
athos@1534
   759
  /// \param g The graph.
athos@1534
   760
  template<typename Graph>
deba@1744
   761
  UndirGraphReader<Graph> undirGraphReader(std::istream& is, Graph &g) {
deba@1744
   762
    return GraphReader<Graph>(is, g);
athos@1534
   763
  }
athos@1534
   764
deba@1744
   765
  /// \brief Read an undirected graph from the input.
athos@1534
   766
  ///
deba@1744
   767
  /// It is a helper function to read an undirected graph from the given input
deba@1744
   768
  /// file. It gives back an UndirGraphReader object and this object
deba@1744
   769
  /// can read more maps, labeled nodes, edges, undirected edges and 
deba@1744
   770
  /// attributes.
deba@1744
   771
  ///
deba@1744
   772
  /// \warning Do not forget to call the \c run() function.
deba@1744
   773
  ///
deba@1744
   774
  /// \param fn The input filename.
deba@1421
   775
  /// \param g The graph.
deba@1744
   776
  template<typename Graph>
deba@1744
   777
  UndirGraphReader<Graph> undirGraphReader(const std::string& fn, Graph &g) {
deba@1744
   778
    return GraphReader<Graph>(fn, g);
deba@1421
   779
  }
deba@1421
   780
deba@1333
   781
  /// @}
deba@1137
   782
}
deba@1214
   783
deba@1214
   784
#endif