lemon/graph_reader.h
author deba
Wed, 06 Sep 2006 09:54:46 +0000
changeset 2198 416b0c06b5c8
parent 2084 59769591eb60
child 2200 2f2ac1b1ca1e
permissions -rw-r--r--
Using abort() instead of exit(1)

If a program is aborted then the call stack can be analyzed with debugger.
The exit(1) does not provides that.
     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 lemon_io
    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 lemon_io
    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   /// The file to be read may contain several maps and labeled nodes or 
    43   /// edges.
    44   ///
    45   /// If you read a graph you need not read all the maps and items just those
    46   /// that you need. The interface of the \c GraphReader is very similar to
    47   /// the GraphWriter but the reading method does not depend on the order the
    48   /// given commands (i.e. you don't have to insist on the order in which the
    49   /// maps are given in the file).
    50   ///
    51   /// The reader object assumes that not read values do not contain 
    52   /// whitespaces, therefore it has some extra possibilities to control how
    53   /// it should skip the values when the string representation contains spaces.
    54   ///
    55   ///\code
    56   /// GraphReader<ListGraph> reader(std::cin, graph);
    57   ///\endcode
    58   ///
    59   /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
    60   /// If there is a map that you do not want to read from the file and there is
    61   /// whitespace in the string represenation of the values then you should
    62   /// call the \c skipNodeMap() template member function with proper 
    63   /// parameters.
    64   ///
    65   ///\code
    66   /// reader.readNodeMap("coords", coords);
    67   ///
    68   /// reader.skipNodeMap("description", desc);
    69   ///
    70   /// reader.readNodeMap("color", colorMap);
    71   ///\endcode
    72   ///
    73   /// With the \c readEdgeMap() member function you can give an edge map
    74   /// reading command similar to the NodeMaps. 
    75   ///
    76   ///\code
    77   /// reader.readEdgeMap("weight", weightMap);
    78   /// reader.readEdgeMap("label", labelMap);
    79   ///\endcode
    80   ///
    81   /// With \c readNode() and \c readEdge() functions you can read 
    82   /// labeled Nodes and Edges.
    83   ///
    84   ///\code
    85   /// reader.readNode("source", sourceNode);
    86   /// reader.readNode("target", targetNode);
    87   ///
    88   /// reader.readEdge("observed", edge);
    89   ///\endcode
    90   ///
    91   /// With the \c readAttribute() functions you can read an attribute
    92   /// into a variable. You can specify the reader for the attribute as
    93   /// the nodemaps.
    94   ///
    95   /// After you give all read commands you must call the \c run() member
    96   /// function, which executes all the commands.
    97   ///
    98   ///\code
    99   /// reader.run();
   100   ///\endcode
   101   ///
   102   /// \see DefaultReaderTraits
   103   /// \see QuotedStringReader
   104   /// \see \ref GraphWriter
   105   /// \see \ref graph-io-page
   106   /// \author Balazs Dezso
   107   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   108   class GraphReader {
   109   public:
   110     
   111     typedef _Graph Graph;
   112     typedef typename Graph::Node Node;
   113     typedef typename Graph::Edge Edge;
   114 
   115     typedef _ReaderTraits ReaderTraits;
   116     typedef typename ReaderTraits::Skipper DefaultSkipper;
   117 
   118     /// \brief Construct a new GraphReader.
   119     ///
   120     /// Construct a new GraphReader. It reads into the given graph
   121     /// and it uses the given reader as the default skipper.
   122     GraphReader(std::istream& _is, Graph& _graph, 
   123 		const DefaultSkipper& _skipper = DefaultSkipper()) 
   124       : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
   125 	nodeset_reader(*reader, _graph, std::string(), skipper),
   126 	edgeset_reader(*reader, _graph, nodeset_reader, 
   127 		       std::string(), skipper),
   128 	node_reader(*reader, nodeset_reader, std::string()),
   129 	edge_reader(*reader, edgeset_reader, std::string()),
   130 	attribute_reader(*reader, std::string()) {}
   131 
   132     /// \brief Construct a new GraphReader.
   133     ///
   134     /// Construct a new GraphReader. It reads into the given graph
   135     /// and it uses the given reader as the default skipper.
   136     GraphReader(const std::string& _filename, Graph& _graph, 
   137 		const DefaultSkipper& _skipper = DefaultSkipper()) 
   138       : reader(new LemonReader(_filename)), own_reader(true), 
   139 	skipper(_skipper),
   140 	nodeset_reader(*reader, _graph, std::string(), skipper),
   141 	edgeset_reader(*reader, _graph, nodeset_reader, 
   142 		       std::string(), skipper),
   143 	node_reader(*reader, nodeset_reader, std::string()),
   144 	edge_reader(*reader, edgeset_reader, std::string()),
   145 	attribute_reader(*reader, std::string()) {}
   146 
   147     /// \brief Construct a new GraphReader.
   148     ///
   149     /// Construct a new GraphReader. It reads into the given graph
   150     /// and it uses the given reader as the default skipper.
   151     GraphReader(LemonReader& _reader, Graph& _graph, 
   152 		const DefaultSkipper& _skipper = DefaultSkipper()) 
   153       : reader(_reader), own_reader(false), skipper(_skipper),
   154 	nodeset_reader(*reader, _graph, std::string(), skipper),
   155 	edgeset_reader(*reader, _graph, nodeset_reader, 
   156 		       std::string(), skipper),
   157 	node_reader(*reader, nodeset_reader, std::string()),
   158 	edge_reader(*reader, edgeset_reader, std::string()),
   159 	attribute_reader(*reader, std::string()) {}
   160 
   161     /// \brief Destruct the graph reader.
   162     ///
   163     /// Destruct the graph reader.
   164     ~GraphReader() {
   165       if (own_reader) 
   166 	delete reader;
   167     }
   168 
   169     /// \brief Give a new node map reading command to the reader.
   170     ///
   171     /// Give a new node map reading command to the reader.
   172     template <typename Map>
   173     GraphReader& readNodeMap(std::string name, Map& map) {
   174       nodeset_reader.readNodeMap(name, map);
   175       return *this;
   176     }
   177 
   178     template <typename Map>
   179     GraphReader& readNodeMap(std::string name, const Map& map) {
   180       nodeset_reader.readNodeMap(name, map);
   181       return *this;
   182     }
   183 
   184     /// \brief Give a new node map reading command to the reader.
   185     ///
   186     /// Give a new node map reading command to the reader.
   187     template <typename Reader, typename Map>
   188     GraphReader& readNodeMap(std::string name, Map& map, 
   189 			     const Reader& reader = Reader()) {
   190       nodeset_reader.readNodeMap(name, map, reader);
   191       return *this;
   192     }
   193 
   194     template <typename Reader, typename Map>
   195     GraphReader& readNodeMap(std::string name, const Map& map, 
   196 			     const Reader& reader = Reader()) {
   197       nodeset_reader.readNodeMap(name, map, reader);
   198       return *this;
   199     }
   200 
   201     /// \brief Give a new node map skipping command to the reader.
   202     ///
   203     /// Give a new node map skipping command to the reader.
   204     template <typename Reader>
   205     GraphReader& skipNodeMap(std::string name, 
   206 			     const Reader& reader = Reader()) {
   207       nodeset_reader.skipNodeMap(name, reader);
   208       return *this;
   209     }
   210 
   211     /// \brief Give a new edge map reading command to the reader.
   212     ///
   213     /// Give a new edge map reading command to the reader.
   214     template <typename Map>
   215     GraphReader& readEdgeMap(std::string name, Map& map) { 
   216       edgeset_reader.readEdgeMap(name, map);
   217       return *this;
   218     }
   219 
   220     template <typename Map>
   221     GraphReader& readEdgeMap(std::string name, const Map& map) { 
   222       edgeset_reader.readEdgeMap(name, map);
   223       return *this;
   224     }
   225 
   226 
   227     /// \brief Give a new edge map reading command to the reader.
   228     ///
   229     /// Give a new edge map reading command to the reader.
   230     template <typename Reader, typename Map>
   231     GraphReader& readEdgeMap(std::string name, Map& map,
   232 			     const Reader& reader = Reader()) {
   233       edgeset_reader.readEdgeMap(name, map, reader);
   234       return *this;
   235     }
   236 
   237     template <typename Reader, typename Map>
   238     GraphReader& readEdgeMap(std::string name, const Map& map,
   239 			     const Reader& reader = Reader()) {
   240       edgeset_reader.readEdgeMap(name, map, reader);
   241       return *this;
   242     }
   243 
   244     /// \brief Give a new edge map skipping command to the reader.
   245     ///
   246     /// Give a new edge map skipping command to the reader.
   247     template <typename Reader>
   248     GraphReader& skipEdgeMap(std::string name, 
   249 			     const Reader& reader = Reader()) {
   250       edgeset_reader.skipEdgeMap(name, reader);
   251       return *this;
   252     }
   253 
   254     /// \brief Give a new labeled node reading command to the reader.
   255     ///
   256     /// Give a new labeled node reading command to the reader.
   257     GraphReader& readNode(std::string name, Node& node) {
   258       node_reader.readNode(name, node);
   259       return *this;
   260     }
   261 
   262     /// \brief Give a new labeled edge reading command to the reader.
   263     ///
   264     /// Give a new labeled edge reading command to the reader.
   265     GraphReader& readEdge(std::string name, Edge& edge) {
   266       edge_reader.readEdge(name, edge);
   267       return *this;
   268     }
   269 
   270     /// \brief Give a new attribute reading command.
   271     ///
   272     ///  Give a new attribute reading command.
   273     template <typename Value>
   274     GraphReader& readAttribute(std::string name, Value& value) {
   275       attribute_reader.readAttribute(name, value);
   276       return *this;
   277     }
   278     
   279     /// \brief Give a new attribute reading command.
   280     ///
   281     ///  Give a new attribute reading command.
   282     template <typename Reader, typename Value>
   283     GraphReader& readAttribute(std::string name, Value& value, 
   284 			       const Reader& reader) {
   285       attribute_reader.readAttribute<Reader>(name, value, reader);
   286       return *this;
   287     }
   288 
   289     /// \brief Conversion operator to LemonReader.
   290     ///
   291     /// Conversion operator to LemonReader. It makes possible to access the
   292     /// encapsulated \e LemonReader, this way you can attach to this reader
   293     /// new instances of \e LemonReader::SectionReader. For more details see
   294     /// the \ref rwbackground "Background of Reading and Writing".
   295     operator LemonReader&() {
   296       return *reader;
   297     }
   298 
   299     /// \brief Executes the reading commands.
   300     ///
   301     /// Executes the reading commands.
   302     void run() {
   303       reader->run();
   304     }
   305 
   306 
   307     /// \brief Returns true if the reader can give back the items by its label.
   308     ///
   309     /// \brief Returns true if the reader can give back the items by its label.
   310     bool isLabelReader() const {
   311       return nodeset_reader.isLabelReader() && edgeset_reader.isLabelReader();
   312     }
   313 
   314     /// \brief Gives back the node by its label.
   315     ///
   316     /// It reads an label from the stream and gives back which node belongs to
   317     /// it. It is possible only if there was read a "label" named node map.
   318     void readLabel(std::istream& is, Node& node) const {
   319       nodeset_reader.readLabel(is, node);
   320     } 
   321 
   322     /// \brief Gives back the edge by its label.
   323     ///
   324     /// It reads an label from the stream and gives back which edge belongs to
   325     /// it. It is possible only if there was read a "label" named edge map.
   326     void readLabel(std::istream& is, Edge& edge) const {
   327       return edgeset_reader.readLabel(is, edge);
   328     } 
   329 
   330   private:
   331 
   332     LemonReader* reader;
   333     bool own_reader;
   334 
   335     DefaultSkipper skipper;
   336 
   337     NodeSetReader<Graph, ReaderTraits> nodeset_reader;
   338     EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
   339 
   340     NodeReader<Graph> node_reader;
   341     EdgeReader<Graph> edge_reader;
   342     
   343     AttributeReader<ReaderTraits> attribute_reader;
   344   };
   345 
   346 
   347   /// \brief Read a graph from the input.
   348   ///
   349   /// It is a helper function to read a graph from the given input
   350   /// stream. It gives back an GraphReader object and this object
   351   /// can read more maps, labeled nodes, edges and attributes.
   352   ///
   353   /// \warning Do not forget to call the \c run() function.
   354   ///
   355   /// \param is The input stream.
   356   /// \param g The graph.
   357   template<typename Graph>
   358   GraphReader<Graph> graphReader(std::istream& is, Graph &g) {
   359     return GraphReader<Graph>(is, g);
   360   }
   361 
   362   /// \brief Read a graph from the input.
   363   ///
   364   /// It is a helper function to read a graph from the given input
   365   /// file. It gives back an GraphReader object and this object
   366   /// can read more maps, labeled nodes, edges and attributes.
   367   ///
   368   /// \warning Do not forget to call the \c run() function.
   369   ///
   370   /// \param fn The input filename.
   371   /// \param g The graph.
   372   template<typename Graph>
   373   GraphReader<Graph> graphReader(const std::string& fn, Graph &g) {
   374     return GraphReader<Graph>(fn, g);
   375   }
   376 
   377   /// \brief The undirected graph reader class.
   378   ///
   379   /// The \c UGraphReader class provides the graph input. 
   380   /// Before you read this documentation it might be useful to read the general
   381   /// description of  \ref graph-io-page "Graph Input-Output".
   382   ///
   383   /// The given file format may contain several maps and labeled nodes or 
   384   /// edges.
   385   ///
   386   /// If you read a graph you need not read all the maps and items just those
   387   /// that you need. The interface of the \c UGraphReader is very similar
   388   /// to the UGraphWriter but the reading method does not depend on the
   389   /// order of the given commands.
   390   ///
   391   /// The reader object suppose that each not read value does not contain 
   392   /// whitespaces, therefore it has some extra possibilities to control how
   393   /// it should skip the values when the string representation contains spaces.
   394   ///
   395   ///\code
   396   /// UGraphReader<ListUGraph> reader(std::cin, graph);
   397   ///\endcode
   398   ///
   399   /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
   400   /// If there is a map that you do not want to read from the file and there is
   401   /// whitespace in the string represenation of the values then you should
   402   /// call the \c skipNodeMap() template member function with proper 
   403   /// parameters.
   404   ///
   405   ///\code
   406   /// reader.readNodeMap("coords", coords);
   407   ///
   408   /// reader.skipNodeMap("description", desc);
   409   ///
   410   /// reader.readNodeMap("color", colorMap);
   411   ///\endcode
   412   ///
   413   /// With the \c readUEdgeMap() member function you can give an 
   414   /// uedge map reading command similar to the NodeMaps. 
   415   ///
   416   ///\code
   417   /// reader.readUEdgeMap("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 readUEdge() functions you can read 
   430   /// labeled Nodes and UEdges.
   431   ///
   432   ///\code
   433   /// reader.readNode("source", sourceNode);
   434   /// reader.readNode("target", targetNode);
   435   ///
   436   /// reader.readUEdge("observed", uEdge);
   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 UGraphWriter
   453   /// \see \ref graph-io-page
   454   ///
   455   /// \author Balazs Dezso
   456   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   457   class UGraphReader {
   458   public:
   459     
   460     typedef _Graph Graph;
   461     typedef typename Graph::Node Node;
   462     typedef typename Graph::Edge Edge;
   463     typedef typename Graph::UEdge UEdge;
   464 
   465     typedef _ReaderTraits ReaderTraits;
   466     typedef typename ReaderTraits::Skipper DefaultSkipper;
   467 
   468     /// \brief Construct a new UGraphReader.
   469     ///
   470     /// Construct a new UGraphReader. It reads into the given graph
   471     /// and it use the given reader as the default skipper.
   472     UGraphReader(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 	u_edgeset_reader(*reader, _graph, nodeset_reader, 
   477 			     std::string(), skipper),
   478 	node_reader(*reader, nodeset_reader, std::string()),
   479 	u_edge_reader(*reader, u_edgeset_reader, std::string()),
   480 	attribute_reader(*reader, std::string()) {}
   481 
   482     /// \brief Construct a new UGraphReader.
   483     ///
   484     /// Construct a new UGraphReader. It reads into the given graph
   485     /// and it use the given reader as the default skipper.
   486     UGraphReader(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 	u_edgeset_reader(*reader, _graph, nodeset_reader, 
   492 			     std::string(), skipper),
   493 	node_reader(*reader, nodeset_reader, std::string()),
   494 	u_edge_reader(*reader, u_edgeset_reader, std::string()),
   495 	attribute_reader(*reader, std::string()) {}
   496 
   497     /// \brief Construct a new UGraphReader.
   498     ///
   499     /// Construct a new UGraphReader. It reads into the given graph
   500     /// and it use the given reader as the default skipper.
   501     UGraphReader(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 	u_edgeset_reader(*reader, _graph, nodeset_reader, 
   506 			     std::string(), skipper),
   507 	node_reader(*reader, nodeset_reader, std::string()),
   508 	u_edge_reader(*reader, u_edgeset_reader, std::string()),
   509 	attribute_reader(*reader, std::string()) {}
   510 
   511     /// \brief Destruct the graph reader.
   512     ///
   513     /// Destruct the graph reader.
   514     ~UGraphReader() {
   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     UGraphReader& readNodeMap(std::string name, Map& map) {
   524       nodeset_reader.readNodeMap(name, map);
   525       return *this;
   526     }
   527 
   528     template <typename Map>
   529     UGraphReader& 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     UGraphReader& 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     UGraphReader& 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     UGraphReader& 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     UGraphReader& readUEdgeMap(std::string name, Map& map) { 
   566       u_edgeset_reader.readUEdgeMap(name, map);
   567       return *this;
   568     }
   569 
   570     template <typename Map>
   571     UGraphReader& readUEdgeMap(std::string name, const Map& map) { 
   572       u_edgeset_reader.readUEdgeMap(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     UGraphReader& readUEdgeMap(std::string name, Map& map,
   582 				       const Reader& reader = Reader()) {
   583       u_edgeset_reader.readUEdgeMap(name, map, reader);
   584       return *this;
   585     }
   586 
   587     template <typename Reader, typename Map>
   588     UGraphReader& readUEdgeMap(std::string name, const Map& map,
   589 				       const Reader& reader = Reader()) {
   590       u_edgeset_reader.readUEdgeMap(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     UGraphReader& skipUEdgeMap(std::string name,
   599 				       const Reader& reader = Reader()) {
   600       u_edgeset_reader.skipUMap(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     UGraphReader& readEdgeMap(std::string name, Map& map) { 
   610       u_edgeset_reader.readEdgeMap(name, map);
   611       return *this;
   612     }
   613 
   614     template <typename Map>
   615     UGraphReader& readEdgeMap(std::string name, const Map& map) { 
   616       u_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     UGraphReader& readEdgeMap(std::string name, Map& map,
   626 				       const Reader& reader = Reader()) {
   627       u_edgeset_reader.readEdgeMap(name, map, reader);
   628       return *this;
   629     }
   630 
   631     template <typename Reader, typename Map>
   632     UGraphReader& readEdgeMap(std::string name, const Map& map,
   633 				       const Reader& reader = Reader()) {
   634       u_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     UGraphReader& skipEdgeMap(std::string name,
   643 				       const Reader& reader = Reader()) {
   644       u_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     UGraphReader& 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     UGraphReader& readEdge(std::string name, Edge& edge) {
   660       u_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     UGraphReader& readUEdge(std::string name, UEdge& edge) {
   668       u_edge_reader.readUEdge(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     UGraphReader& 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     UGraphReader& 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 
   708     /// \brief Returns true if the reader can give back the items by its label.
   709     ///
   710     /// \brief Returns true if the reader can give back the items by its label.
   711     bool isLabelReader() const {
   712       return nodeset_reader.isLabelReader() && 
   713         u_edgeset_reader.isLabelReader();
   714     }
   715 
   716     /// \brief Gives back the node by its label.
   717     ///
   718     /// It reads an label from the stream and gives back which node belongs to
   719     /// it. It is possible only if there was read a "label" named node map.
   720     void readLabel(std::istream& is, Node& node) const {
   721       return nodeset_reader.readLabel(is, node);
   722     } 
   723 
   724     /// \brief Gives back the edge by its label
   725     ///
   726     /// It reads an label from the stream and gives back which edge belongs to
   727     /// it. It is possible only if there was read a "label" named edge map.
   728     void readLabel(std::istream& is, Edge& edge) const {
   729       return u_edgeset_reader.readLabel(is, edge);
   730     } 
   731 
   732     /// \brief Gives back the undirected edge by its label.
   733     ///
   734     /// It reads an label from the stream and gives back which undirected edge 
   735     /// belongs to it. It is possible only if there was read a "label" named 
   736     /// edge map.
   737     void readLabel(std::istream& is, UEdge& uedge) const {
   738       return u_edgeset_reader.readLabel(is, uedge);
   739     } 
   740     
   741 
   742   private:
   743 
   744     LemonReader* reader;
   745     bool own_reader;
   746 
   747     DefaultSkipper skipper;
   748 
   749     NodeSetReader<Graph, ReaderTraits> nodeset_reader;
   750     UEdgeSetReader<Graph, ReaderTraits> u_edgeset_reader;
   751 
   752     NodeReader<Graph> node_reader;
   753     UEdgeReader<Graph> u_edge_reader;
   754     
   755     AttributeReader<ReaderTraits> attribute_reader;
   756   };
   757 
   758   /// \brief Read an undirected graph from the input.
   759   ///
   760   /// It is a helper function to read an undirected graph from the given input
   761   /// stream. It gives back an UGraphReader object and this object
   762   /// can read more maps, labeled nodes, edges, undirected edges and
   763   /// attributes.
   764   ///
   765   /// \warning Do not forget to call the \c run() function.
   766   ///
   767   /// \param is The input stream.
   768   /// \param g The graph.
   769   template<typename Graph>
   770   UGraphReader<Graph> uGraphReader(std::istream& is, Graph &g) {
   771     return GraphReader<Graph>(is, g);
   772   }
   773 
   774   /// \brief Read an undirected graph from the input.
   775   ///
   776   /// It is a helper function to read an undirected graph from the given input
   777   /// file. It gives back an UGraphReader object and this object
   778   /// can read more maps, labeled nodes, edges, undirected edges and 
   779   /// attributes.
   780   ///
   781   /// \warning Do not forget to call the \c run() function.
   782   ///
   783   /// \param fn The input filename.
   784   /// \param g The graph.
   785   template<typename Graph>
   786   UGraphReader<Graph> uGraphReader(const std::string& fn, Graph &g) {
   787     return GraphReader<Graph>(fn, g);
   788   }
   789 
   790   /// @}
   791 }
   792 
   793 #endif