src/lemon/graph_reader.h
author deba
Wed, 11 May 2005 13:49:17 +0000
changeset 1411 5d161e08bda8
parent 1396 56f9a4ba9149
child 1421 7a21e1414c38
permissions -rw-r--r--
Bug fix.
deba@1137
     1
/* -*- C++ -*-
deba@1137
     2
 * src/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
  ///
deba@1333
    36
  /// The given file format may contain several maps and labeled nodes or 
deba@1333
    37
  /// edges.
deba@1333
    38
  ///
deba@1333
    39
  /// If you read a graph you need not read all the maps and items just those
deba@1333
    40
  /// that you need. The interface of the \c GraphReader is very similar to
deba@1333
    41
  /// the GraphWriter but the reading method does not depend on the order the
deba@1333
    42
  /// given commands.
deba@1333
    43
  ///
deba@1333
    44
  /// The reader object suppose that each not readed value does not contain 
deba@1333
    45
  /// whitespaces, therefore it has some extra possibilities to control how
deba@1333
    46
  /// it should skip the values when the string representation contains spaces.
deba@1333
    47
  ///
deba@1333
    48
  /// \code
deba@1333
    49
  /// GraphReader<ListGraph> reader(std::cin, graph);
deba@1333
    50
  /// \endcode
deba@1333
    51
  ///
deba@1394
    52
  /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
deba@1333
    53
  /// If there is a map that you do not want to read from the file and there is
deba@1333
    54
  /// whitespace in the string represenation of the values then you should
deba@1333
    55
  /// call the \c skipNodeMap() template member function with proper 
deba@1333
    56
  /// parameters.
deba@1333
    57
  ///
deba@1333
    58
  /// \code
deba@1394
    59
  /// reader.readNodeMap("x-coord", xCoordMap);
deba@1394
    60
  /// reader.readNodeMap("y-coord", yCoordMap);
deba@1333
    61
  ///
deba@1394
    62
  /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
deba@1333
    63
  /// reader.skipNodeMap<QuotedStringReader>("description");
deba@1333
    64
  ///
deba@1394
    65
  /// reader.readNodeMap("color", colorMap);
deba@1333
    66
  /// \endcode
deba@1333
    67
  ///
deba@1394
    68
  /// With the \c readEdgeMap() member function you can give an edge map
deba@1333
    69
  /// reading command similar to the NodeMaps. 
deba@1333
    70
  ///
deba@1333
    71
  /// \code
deba@1394
    72
  /// reader.readEdgeMap("weight", weightMap);
deba@1394
    73
  /// reader.readEdgeMap("label", labelMap);
deba@1333
    74
  /// \endcode
deba@1333
    75
  ///
deba@1408
    76
  /// With \c readNode() and \c readEdge() functions you can read 
deba@1408
    77
  /// labeled Nodes and Edges.
deba@1333
    78
  ///
deba@1333
    79
  /// \code
deba@1394
    80
  /// reader.readNode("source", sourceNode);
deba@1394
    81
  /// reader.readNode("target", targetNode);
deba@1333
    82
  ///
deba@1394
    83
  /// reader.readEdge("observed", edge);
deba@1333
    84
  /// \endcode
deba@1333
    85
  ///
deba@1408
    86
  /// With the \c readAttribute() functions you can read an attribute
deba@1408
    87
  /// in a variable. You can specify the reader for the attribute as
deba@1408
    88
  /// the nodemaps.
deba@1408
    89
  ///
deba@1333
    90
  /// After you give all read commands you must call the \c run() member
deba@1333
    91
  /// function, which execute all the commands.
deba@1333
    92
  ///
deba@1333
    93
  /// \code
deba@1333
    94
  /// reader.run();
deba@1333
    95
  /// \endcode
deba@1333
    96
  ///
alpar@1287
    97
  /// \see DefaultReaderTraits
alpar@1287
    98
  /// \see QuotedStringReader
alpar@1138
    99
  /// \see \ref GraphWriter
alpar@1138
   100
  /// \see \ref graph-io-page
deba@1333
   101
  /// \author Balazs Dezso
deba@1137
   102
  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
deba@1137
   103
  class GraphReader {
deba@1137
   104
  public:
deba@1137
   105
    
deba@1137
   106
    typedef _Graph Graph;
deba@1137
   107
    typedef typename Graph::Node Node;
deba@1137
   108
    typedef typename Graph::Edge Edge;
deba@1137
   109
deba@1137
   110
    typedef _ReaderTraits ReaderTraits;
deba@1408
   111
    typedef typename ReaderTraits::Skipper DefaultSkipper;
deba@1137
   112
deba@1137
   113
    /// \brief Construct a new GraphReader.
deba@1137
   114
    ///
deba@1208
   115
    /// Construct a new GraphReader. It reads into the given graph
deba@1208
   116
    /// and it use the given reader as the default skipper.
deba@1137
   117
    GraphReader(std::istream& _is, Graph& _graph, 
deba@1408
   118
		const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1408
   119
      : reader(new LemonReader(_is)), own_reader(true), 
deba@1408
   120
	graph(_graph), skipper(_skipper),
deba@1408
   121
	nodeset_reader(*reader, graph, std::string(), skipper),
deba@1408
   122
	edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
deba@1408
   123
	node_reader(*reader, nodeset_reader, std::string()),
deba@1408
   124
	edge_reader(*reader, edgeset_reader, std::string()),
deba@1408
   125
	attribute_reader(*reader, std::string()) {}
deba@1408
   126
deba@1408
   127
    /// \brief Construct a new GraphReader.
deba@1408
   128
    ///
deba@1408
   129
    /// Construct a new GraphReader. It reads into the given graph
deba@1408
   130
    /// and it use the given reader as the default skipper.
deba@1408
   131
    GraphReader(const std::string& _filename, Graph& _graph, 
deba@1408
   132
		const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1408
   133
      : reader(new LemonReader(_filename)), own_reader(true), 
deba@1408
   134
	graph(_graph), skipper(_skipper),
deba@1408
   135
	nodeset_reader(*reader, graph, std::string(), skipper),
deba@1408
   136
	edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
deba@1408
   137
	node_reader(*reader, nodeset_reader, std::string()),
deba@1408
   138
	edge_reader(*reader, edgeset_reader, std::string()),
deba@1408
   139
	attribute_reader(*reader, std::string()) {}
deba@1408
   140
deba@1408
   141
    /// \brief Construct a new GraphReader.
deba@1408
   142
    ///
deba@1408
   143
    /// Construct a new GraphReader. It reads into the given graph
deba@1408
   144
    /// and it use the given reader as the default skipper.
deba@1408
   145
    GraphReader(LemonReader& _reader, Graph& _graph, 
deba@1408
   146
		const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1408
   147
      : reader(_reader), own_reader(false), 
deba@1408
   148
	graph(_graph), skipper(_skipper),
deba@1408
   149
	nodeset_reader(*reader, graph, std::string(), skipper),
deba@1408
   150
	edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
deba@1408
   151
	node_reader(*reader, nodeset_reader, std::string()),
deba@1408
   152
	edge_reader(*reader, edgeset_reader, std::string()),
deba@1408
   153
	attribute_reader(*reader, std::string()) {}
deba@1137
   154
deba@1137
   155
    /// \brief Destruct the graph reader.
deba@1137
   156
    ///
deba@1137
   157
    /// Destruct the graph reader.
deba@1137
   158
    ~GraphReader() {
deba@1408
   159
      if (own_reader) 
deba@1408
   160
	delete reader;
deba@1137
   161
    }
deba@1137
   162
deba@1137
   163
    /// \brief Add a new node map reader command for the reader.
deba@1137
   164
    ///
deba@1137
   165
    /// Add a new node map reader command for the reader.
deba@1137
   166
    template <typename Map>
deba@1394
   167
    GraphReader& readNodeMap(std::string name, Map& map) {
deba@1408
   168
      nodeset_reader.readMap(name, map);
deba@1408
   169
      return *this;
deba@1137
   170
    }
deba@1137
   171
deba@1137
   172
    /// \brief Add a new node map reader command for the reader.
deba@1137
   173
    ///
deba@1137
   174
    /// Add a new node map reader command for the reader.
deba@1137
   175
    template <typename Reader, typename Map>
deba@1394
   176
    GraphReader& readNodeMap(std::string name, Map& map, 
deba@1137
   177
			     const Reader& reader = Reader()) {
deba@1408
   178
      nodeset_reader.readMap(name, map, reader);
deba@1137
   179
      return *this;
deba@1137
   180
    }
deba@1137
   181
deba@1137
   182
    /// \brief Add a new node map skipper command for the reader.
deba@1137
   183
    ///
deba@1137
   184
    /// Add a new node map skipper command for the reader.
deba@1137
   185
    template <typename Reader>
deba@1137
   186
    GraphReader& skipNodeMap(std::string name, 
deba@1137
   187
			     const Reader& reader = Reader()) {
deba@1408
   188
      nodeset_reader.skipMap(name, reader);
deba@1137
   189
      return *this;
deba@1137
   190
    }
deba@1137
   191
deba@1137
   192
    /// \brief Add a new edge map reader command for the reader.
deba@1137
   193
    ///
deba@1137
   194
    /// Add a new edge map reader command for the reader.
deba@1137
   195
    template <typename Map>
deba@1394
   196
    GraphReader& readEdgeMap(std::string name, Map& map) { 
deba@1408
   197
      edgeset_reader.readMap(name, map);
deba@1408
   198
      return *this;
deba@1137
   199
    }
deba@1137
   200
deba@1137
   201
deba@1137
   202
    /// \brief Add a new edge map reader command for the reader.
deba@1137
   203
    ///
deba@1137
   204
    /// Add a new edge map reader command for the reader.
deba@1137
   205
    template <typename Reader, typename Map>
deba@1394
   206
    GraphReader& readEdgeMap(std::string name, Map& map,
deba@1137
   207
			     const Reader& reader = Reader()) {
deba@1408
   208
      edgeset_reader.readMap(name, map, reader);
deba@1137
   209
      return *this;
deba@1137
   210
    }
deba@1137
   211
deba@1137
   212
    /// \brief Add a new edge map skipper command for the reader.
deba@1137
   213
    ///
deba@1137
   214
    /// Add a new edge map skipper command for the reader.
deba@1137
   215
    template <typename Reader>
deba@1137
   216
    GraphReader& skipEdgeMap(std::string name,
deba@1137
   217
			     const Reader& reader = Reader()) {
deba@1408
   218
deba@1408
   219
      edgeset_reader.skipMap(name, reader);
deba@1137
   220
      return *this;
deba@1137
   221
    }
deba@1137
   222
deba@1137
   223
    /// \brief Add a new labeled node reader for the reader.
deba@1137
   224
    ///
deba@1137
   225
    /// Add a new labeled node reader for the reader.
deba@1394
   226
    GraphReader& readNode(std::string name, Node& node) {
deba@1408
   227
      node_reader.readNode(name, node);
deba@1137
   228
      return *this;
deba@1137
   229
    }
deba@1137
   230
deba@1137
   231
    /// \brief Add a new labeled edge reader for the reader.
deba@1137
   232
    ///
deba@1137
   233
    /// Add a new labeled edge reader for the reader.
deba@1394
   234
    GraphReader& readEdge(std::string name, Edge& edge) {
deba@1408
   235
      edge_reader.readEdge(name, edge);
deba@1408
   236
    }
deba@1408
   237
deba@1408
   238
    /// \brief Add a new attribute reader command.
deba@1408
   239
    ///
deba@1408
   240
    ///  Add a new attribute reader command.
deba@1408
   241
    template <typename Value>
deba@1408
   242
    GraphReader& readAttribute(std::string name, Value& value) {
deba@1408
   243
      attribute_reader.readAttribute(name, value);
deba@1137
   244
      return *this;
deba@1137
   245
    }
deba@1408
   246
    
deba@1408
   247
    /// \brief Add a new attribute reader command.
deba@1408
   248
    ///
deba@1408
   249
    ///  Add a new attribute reader command.
deba@1408
   250
    template <typename Reader, typename Value>
deba@1408
   251
    GraphReader& readAttribute(std::string name, Value& value, 
deba@1408
   252
			       const Reader& reader) {
deba@1408
   253
      attribute_reader.readAttribute<Reader>(name, value, reader);
deba@1408
   254
      return *this;
deba@1408
   255
    }
deba@1408
   256
deba@1408
   257
    /// \brief Conversion operator to LemonReader.
deba@1408
   258
    ///
deba@1408
   259
    /// Conversion operator to LemonReader. It make possible
deba@1408
   260
    /// to access the encapsulated \e LemonReader, this way
deba@1408
   261
    /// you can attach to this reader new instances of 
deba@1408
   262
    /// \e LemonReader::SectionReader.
deba@1408
   263
    operator LemonReader&() {
deba@1408
   264
      return *reader;
deba@1408
   265
    }
deba@1137
   266
deba@1137
   267
    /// \brief Executes the reader commands.
deba@1137
   268
    ///
deba@1137
   269
    /// Executes the reader commands.
deba@1137
   270
    void run() {
deba@1408
   271
      reader->run();
deba@1396
   272
    }
deba@1396
   273
deba@1137
   274
  private:
deba@1137
   275
deba@1408
   276
    LemonReader* reader;
deba@1408
   277
    bool own_reader;
deba@1137
   278
deba@1137
   279
    Graph& graph;
deba@1137
   280
deba@1408
   281
    DefaultSkipper skipper;
deba@1137
   282
deba@1408
   283
    NodeSetReader<Graph, ReaderTraits> nodeset_reader;
deba@1408
   284
    EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
deba@1408
   285
deba@1408
   286
    NodeReader<Graph> node_reader;
deba@1408
   287
    EdgeReader<Graph> edge_reader;
deba@1408
   288
    
deba@1408
   289
    AttributeReader<ReaderTraits> attribute_reader;
deba@1137
   290
  };
deba@1137
   291
deba@1333
   292
  /// \brief Read a graph from the input.
deba@1333
   293
  ///
deba@1333
   294
  /// Read a graph from the input.
deba@1333
   295
  /// \param is The input stream.
deba@1333
   296
  /// \param g The graph.
deba@1333
   297
  /// \param capacity The capacity map.
deba@1333
   298
  /// \param s The source node.
deba@1333
   299
  /// \param t The target node.
deba@1333
   300
  /// \param cost The cost map.
deba@1208
   301
  template<typename Graph, typename CapacityMap, typename CostMap>
deba@1208
   302
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
deba@1208
   303
		  typename Graph::Node &s, typename Graph::Node &t, 
deba@1208
   304
		  CostMap& cost) {
deba@1208
   305
    GraphReader<Graph> reader(is, g);
deba@1394
   306
    reader.readEdgeMap("capacity", capacity);
deba@1394
   307
    reader.readEdgeMap("cost", cost);
deba@1394
   308
    reader.readNode("source", s);
deba@1394
   309
    reader.readNode("target", t);
deba@1208
   310
    reader.run();
deba@1208
   311
  }
deba@1208
   312
deba@1333
   313
  /// \brief Read a graph from the input.
deba@1333
   314
  ///
deba@1333
   315
  /// Read a graph from the input.
deba@1333
   316
  /// \param is The input stream.
deba@1333
   317
  /// \param g The graph.
deba@1333
   318
  /// \param capacity The capacity map.
deba@1333
   319
  /// \param s The source node.
deba@1333
   320
  /// \param t The target node.
deba@1208
   321
  template<typename Graph, typename CapacityMap>
deba@1208
   322
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
deba@1208
   323
		  typename Graph::Node &s, typename Graph::Node &t) {
deba@1208
   324
    GraphReader<Graph> reader(is, g);
deba@1394
   325
    reader.readEdgeMap("capacity", capacity);
deba@1394
   326
    reader.readNode("source", s);
deba@1394
   327
    reader.readNode("target", t);
deba@1208
   328
    reader.run();
deba@1208
   329
  }
deba@1208
   330
deba@1333
   331
  /// \brief Read a graph from the input.
deba@1333
   332
  ///
deba@1333
   333
  /// Read a graph from the input.
deba@1333
   334
  /// \param is The input stream.
deba@1333
   335
  /// \param g The graph.
deba@1333
   336
  /// \param capacity The capacity map.
deba@1333
   337
  /// \param s The source node.
deba@1208
   338
  template<typename Graph, typename CapacityMap>
deba@1208
   339
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
deba@1208
   340
		  typename Graph::Node &s) {
deba@1208
   341
    GraphReader<Graph> reader(is, g);
deba@1394
   342
    reader.readEdgeMap("capacity", capacity);
deba@1394
   343
    reader.readNode("source", s);
deba@1208
   344
    reader.run();
deba@1208
   345
  }
deba@1208
   346
deba@1333
   347
  /// \brief Read a graph from the input.
deba@1333
   348
  ///
deba@1333
   349
  /// Read a graph from the input.
deba@1333
   350
  /// \param is The input stream.
deba@1333
   351
  /// \param g The graph.
deba@1333
   352
  /// \param capacity The capacity map.
deba@1208
   353
  template<typename Graph, typename CapacityMap>
deba@1208
   354
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
deba@1208
   355
    GraphReader<Graph> reader(is, g);
deba@1394
   356
    reader.readEdgeMap("capacity", capacity);
deba@1208
   357
    reader.run();
deba@1208
   358
  }
deba@1208
   359
deba@1333
   360
  /// \brief Read a graph from the input.
deba@1333
   361
  ///
deba@1333
   362
  /// Read a graph from the input.
deba@1333
   363
  /// \param is The input stream.
deba@1333
   364
  /// \param g The graph.
deba@1208
   365
  template<typename Graph>
deba@1208
   366
  void readGraph(std::istream& is, Graph &g) {
deba@1208
   367
    GraphReader<Graph> reader(is, g);
deba@1208
   368
    reader.run();
deba@1208
   369
  }
deba@1208
   370
deba@1333
   371
  /// @}
deba@1137
   372
}
deba@1214
   373
deba@1214
   374
#endif