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