lemon/graph_reader.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2100 6fbe90faf02a
child 2334 c1e936e6a46b
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

The tests have been modified to the current implementation
     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 The undirected graph reader class.
   348   ///
   349   /// The \c UGraphReader class provides the graph input. 
   350   /// Before you read this documentation it might be useful to read the general
   351   /// description of  \ref graph-io-page "Graph Input-Output".
   352   ///
   353   /// The given file format may contain several maps and labeled nodes or 
   354   /// edges.
   355   ///
   356   /// If you read a graph you need not read all the maps and items just those
   357   /// that you need. The interface of the \c UGraphReader is very similar
   358   /// to the UGraphWriter but the reading method does not depend on the
   359   /// order of the given commands.
   360   ///
   361   /// The reader object suppose that each not read value does not contain 
   362   /// whitespaces, therefore it has some extra possibilities to control how
   363   /// it should skip the values when the string representation contains spaces.
   364   ///
   365   ///\code
   366   /// UGraphReader<ListUGraph> reader(std::cin, graph);
   367   ///\endcode
   368   ///
   369   /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
   370   /// If there is a map that you do not want to read from the file and there is
   371   /// whitespace in the string represenation of the values then you should
   372   /// call the \c skipNodeMap() template member function with proper 
   373   /// parameters.
   374   ///
   375   ///\code
   376   /// reader.readNodeMap("coords", coords);
   377   ///
   378   /// reader.skipNodeMap("description", desc);
   379   ///
   380   /// reader.readNodeMap("color", colorMap);
   381   ///\endcode
   382   ///
   383   /// With the \c readUEdgeMap() member function you can give an 
   384   /// uedge map reading command similar to the NodeMaps. 
   385   ///
   386   ///\code
   387   /// reader.readUEdgeMap("capacity", capacityMap);
   388   ///\endcode
   389   ///
   390   /// The reading of the directed edge maps is just a syntactical sugar.
   391   /// It reads two undirected edgemaps into a directed edge map. The 
   392   /// undirected edge maps' name should be start with the \c '+' and the
   393   /// \c '-' character and the same.
   394   ///
   395   ///\code
   396   /// reader.readEdgeMap("flow", flowMap);
   397   ///\endcode 
   398   ///
   399   /// With \c readNode() and \c readUEdge() functions you can read 
   400   /// labeled Nodes and UEdges.
   401   ///
   402   ///\code
   403   /// reader.readNode("source", sourceNode);
   404   /// reader.readNode("target", targetNode);
   405   ///
   406   /// reader.readUEdge("observed", uEdge);
   407   ///\endcode
   408   ///
   409   /// With the \c readAttribute() functions you can read an attribute
   410   /// in a variable. You can specify the reader for the attribute as
   411   /// the nodemaps.
   412   ///
   413   /// After you give all read commands you must call the \c run() member
   414   /// function, which execute all the commands.
   415   ///
   416   ///\code
   417   /// reader.run();
   418   ///\endcode
   419   ///
   420   /// \see GraphReader
   421   /// \see DefaultReaderTraits
   422   /// \see \ref UGraphWriter
   423   /// \see \ref graph-io-page
   424   ///
   425   /// \author Balazs Dezso
   426   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   427   class UGraphReader {
   428   public:
   429     
   430     typedef _Graph Graph;
   431     typedef typename Graph::Node Node;
   432     typedef typename Graph::Edge Edge;
   433     typedef typename Graph::UEdge UEdge;
   434 
   435     typedef _ReaderTraits ReaderTraits;
   436     typedef typename ReaderTraits::Skipper DefaultSkipper;
   437 
   438     /// \brief Construct a new UGraphReader.
   439     ///
   440     /// Construct a new UGraphReader. It reads into the given graph
   441     /// and it use the given reader as the default skipper.
   442     UGraphReader(std::istream& _is, Graph& _graph, 
   443 		     const DefaultSkipper& _skipper = DefaultSkipper()) 
   444       : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
   445 	nodeset_reader(*reader, _graph, std::string(), skipper),
   446 	u_edgeset_reader(*reader, _graph, nodeset_reader, 
   447 			     std::string(), skipper),
   448 	node_reader(*reader, nodeset_reader, std::string()),
   449 	u_edge_reader(*reader, u_edgeset_reader, std::string()),
   450 	attribute_reader(*reader, std::string()) {}
   451 
   452     /// \brief Construct a new UGraphReader.
   453     ///
   454     /// Construct a new UGraphReader. It reads into the given graph
   455     /// and it use the given reader as the default skipper.
   456     UGraphReader(const std::string& _filename, Graph& _graph, 
   457 		     const DefaultSkipper& _skipper = DefaultSkipper()) 
   458       : reader(new LemonReader(_filename)), own_reader(true), 
   459 	skipper(_skipper),
   460 	nodeset_reader(*reader, _graph, std::string(), skipper),
   461 	u_edgeset_reader(*reader, _graph, nodeset_reader, 
   462 			     std::string(), skipper),
   463 	node_reader(*reader, nodeset_reader, std::string()),
   464 	u_edge_reader(*reader, u_edgeset_reader, std::string()),
   465 	attribute_reader(*reader, std::string()) {}
   466 
   467     /// \brief Construct a new UGraphReader.
   468     ///
   469     /// Construct a new UGraphReader. It reads into the given graph
   470     /// and it use the given reader as the default skipper.
   471     UGraphReader(LemonReader& _reader, Graph& _graph, 
   472 		     const DefaultSkipper& _skipper = DefaultSkipper()) 
   473       : reader(_reader), own_reader(false), skipper(_skipper),
   474 	nodeset_reader(*reader, _graph, std::string(), skipper),
   475 	u_edgeset_reader(*reader, _graph, nodeset_reader, 
   476 			     std::string(), skipper),
   477 	node_reader(*reader, nodeset_reader, std::string()),
   478 	u_edge_reader(*reader, u_edgeset_reader, std::string()),
   479 	attribute_reader(*reader, std::string()) {}
   480 
   481     /// \brief Destruct the graph reader.
   482     ///
   483     /// Destruct the graph reader.
   484     ~UGraphReader() {
   485       if (own_reader) 
   486 	delete reader;
   487     }
   488 
   489     /// \brief Give a new node map reading command to the reader.
   490     ///
   491     /// Give a new node map reading command to the reader.
   492     template <typename Map>
   493     UGraphReader& readNodeMap(std::string name, Map& map) {
   494       nodeset_reader.readNodeMap(name, map);
   495       return *this;
   496     }
   497 
   498     template <typename Map>
   499     UGraphReader& readNodeMap(std::string name, const Map& map) {
   500       nodeset_reader.readNodeMap(name, map);
   501       return *this;
   502     }
   503 
   504     /// \brief Give a new node map reading command to the reader.
   505     ///
   506     /// Give a new node map reading command to the reader.
   507     template <typename Reader, typename Map>
   508     UGraphReader& readNodeMap(std::string name, Map& map, 
   509 				  const Reader& reader = Reader()) {
   510       nodeset_reader.readNodeMap(name, map, reader);
   511       return *this;
   512     }
   513 
   514     template <typename Reader, typename Map>
   515     UGraphReader& readNodeMap(std::string name, const Map& map, 
   516 				  const Reader& reader = Reader()) {
   517       nodeset_reader.readNodeMap(name, map, reader);
   518       return *this;
   519     }
   520 
   521     /// \brief Give a new node map skipping command to the reader.
   522     ///
   523     /// Give a new node map skipping command to the reader.
   524     template <typename Reader>
   525     UGraphReader& skipNodeMap(std::string name, 
   526 			     const Reader& reader = Reader()) {
   527       nodeset_reader.skipNodeMap(name, reader);
   528       return *this;
   529     }
   530 
   531     /// \brief Give a new undirected edge map reading command to the reader.
   532     ///
   533     /// Give a new undirected edge map reading command to the reader.
   534     template <typename Map>
   535     UGraphReader& readUEdgeMap(std::string name, Map& map) { 
   536       u_edgeset_reader.readUEdgeMap(name, map);
   537       return *this;
   538     }
   539 
   540     template <typename Map>
   541     UGraphReader& readUEdgeMap(std::string name, const Map& map) { 
   542       u_edgeset_reader.readUEdgeMap(name, map);
   543       return *this;
   544     }
   545 
   546 
   547     /// \brief Give a new undirected edge map reading command to the reader.
   548     ///
   549     /// Give a new undirected edge map reading command to the reader.
   550     template <typename Reader, typename Map>
   551     UGraphReader& readUEdgeMap(std::string name, Map& map,
   552 				       const Reader& reader = Reader()) {
   553       u_edgeset_reader.readUEdgeMap(name, map, reader);
   554       return *this;
   555     }
   556 
   557     template <typename Reader, typename Map>
   558     UGraphReader& readUEdgeMap(std::string name, const Map& map,
   559 				       const Reader& reader = Reader()) {
   560       u_edgeset_reader.readUEdgeMap(name, map, reader);
   561       return *this;
   562     }
   563 
   564     /// \brief Give a new undirected edge map skipping command to the reader.
   565     ///
   566     /// Give a new undirected edge map skipping command to the reader.
   567     template <typename Reader>
   568     UGraphReader& skipUEdgeMap(std::string name,
   569 				       const Reader& reader = Reader()) {
   570       u_edgeset_reader.skipUMap(name, reader);
   571       return *this;
   572     }
   573 
   574 
   575     /// \brief Give a new edge map reading command to the reader.
   576     ///
   577     /// Give a new edge map reading command to the reader.
   578     template <typename Map>
   579     UGraphReader& readEdgeMap(std::string name, Map& map) { 
   580       u_edgeset_reader.readEdgeMap(name, map);
   581       return *this;
   582     }
   583 
   584     template <typename Map>
   585     UGraphReader& readEdgeMap(std::string name, const Map& map) { 
   586       u_edgeset_reader.readEdgeMap(name, map);
   587       return *this;
   588     }
   589 
   590 
   591     /// \brief Give a new edge map reading command to the reader.
   592     ///
   593     /// Give a new edge map reading command to the reader.
   594     template <typename Reader, typename Map>
   595     UGraphReader& readEdgeMap(std::string name, Map& map,
   596 				       const Reader& reader = Reader()) {
   597       u_edgeset_reader.readEdgeMap(name, map, reader);
   598       return *this;
   599     }
   600 
   601     template <typename Reader, typename Map>
   602     UGraphReader& readEdgeMap(std::string name, const Map& map,
   603 				       const Reader& reader = Reader()) {
   604       u_edgeset_reader.readEdgeMap(name, map, reader);
   605       return *this;
   606     }
   607 
   608     /// \brief Give a new edge map skipping command to the reader.
   609     ///
   610     /// Give a new edge map skipping command to the reader.
   611     template <typename Reader>
   612     UGraphReader& skipEdgeMap(std::string name,
   613 				       const Reader& reader = Reader()) {
   614       u_edgeset_reader.skipEdgeMap(name, reader);
   615       return *this;
   616     }
   617 
   618     /// \brief Give a new labeled node reading command to the reader.
   619     ///
   620     /// Give a new labeled node reading command to the reader.
   621     UGraphReader& readNode(std::string name, Node& node) {
   622       node_reader.readNode(name, node);
   623       return *this;
   624     }
   625 
   626     /// \brief Give a new labeled edge reading command to the reader.
   627     ///
   628     /// Give a new labeled edge reading command to the reader.
   629     UGraphReader& readEdge(std::string name, Edge& edge) {
   630       u_edge_reader.readEdge(name, edge);
   631     }
   632 
   633     /// \brief Give a new labeled undirected edge reading command to the
   634     /// reader.
   635     ///
   636     /// Give a new labeled undirected edge reading command to the reader.
   637     UGraphReader& readUEdge(std::string name, UEdge& edge) {
   638       u_edge_reader.readUEdge(name, edge);
   639     }
   640 
   641     /// \brief Give a new attribute reading command.
   642     ///
   643     ///  Give a new attribute reading command.
   644     template <typename Value>
   645     UGraphReader& readAttribute(std::string name, Value& value) {
   646       attribute_reader.readAttribute(name, value);
   647       return *this;
   648     }
   649     
   650     /// \brief Give a new attribute reading command.
   651     ///
   652     ///  Give a new attribute reading command.
   653     template <typename Reader, typename Value>
   654     UGraphReader& readAttribute(std::string name, Value& value, 
   655 			       const Reader& reader) {
   656       attribute_reader.readAttribute<Reader>(name, value, reader);
   657       return *this;
   658     }
   659 
   660     /// \brief Conversion operator to LemonReader.
   661     ///
   662     /// Conversion operator to LemonReader. It make possible
   663     /// to access the encapsulated \e LemonReader, this way
   664     /// you can attach to this reader new instances of 
   665     /// \e LemonReader::SectionReader.
   666     operator LemonReader&() {
   667       return *reader;
   668     }
   669 
   670     /// \brief Executes the reading commands.
   671     ///
   672     /// Executes the reading commands.
   673     void run() {
   674       reader->run();
   675     }
   676 
   677 
   678     /// \brief Returns true if the reader can give back the items by its label.
   679     ///
   680     /// \brief Returns true if the reader can give back the items by its label.
   681     bool isLabelReader() const {
   682       return nodeset_reader.isLabelReader() && 
   683         u_edgeset_reader.isLabelReader();
   684     }
   685 
   686     /// \brief Gives back the node by its label.
   687     ///
   688     /// It reads an label from the stream and gives back which node belongs to
   689     /// it. It is possible only if there was read a "label" named node map.
   690     void readLabel(std::istream& is, Node& node) const {
   691       return nodeset_reader.readLabel(is, node);
   692     } 
   693 
   694     /// \brief Gives back the edge by its label
   695     ///
   696     /// It reads an label from the stream and gives back which edge belongs to
   697     /// it. It is possible only if there was read a "label" named edge map.
   698     void readLabel(std::istream& is, Edge& edge) const {
   699       return u_edgeset_reader.readLabel(is, edge);
   700     } 
   701 
   702     /// \brief Gives back the undirected edge by its label.
   703     ///
   704     /// It reads an label from the stream and gives back which undirected edge 
   705     /// belongs to it. It is possible only if there was read a "label" named 
   706     /// edge map.
   707     void readLabel(std::istream& is, UEdge& uedge) const {
   708       return u_edgeset_reader.readLabel(is, uedge);
   709     } 
   710     
   711 
   712   private:
   713 
   714     LemonReader* reader;
   715     bool own_reader;
   716 
   717     DefaultSkipper skipper;
   718 
   719     NodeSetReader<Graph, ReaderTraits> nodeset_reader;
   720     UEdgeSetReader<Graph, ReaderTraits> u_edgeset_reader;
   721 
   722     NodeReader<Graph> node_reader;
   723     UEdgeReader<Graph> u_edge_reader;
   724     
   725     AttributeReader<ReaderTraits> attribute_reader;
   726   };
   727 
   728 
   729   /// @}
   730 }
   731 
   732 #endif