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