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