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