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