lemon/graph_reader.h
author hegyi
Mon, 21 Nov 2005 18:03:20 +0000
changeset 1823 cb082cdf3667
parent 1705 3f63d9db307b
child 1875 98698b69a902
permissions -rw-r--r--
NewMapWin has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.
     1 /* -*- C++ -*-
     2  * lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 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