lemon/graph_reader.h
author athos
Mon, 30 Oct 2006 12:01:51 +0000
changeset 2268 ad15bdd334bf
parent 2100 6fbe90faf02a
child 2334 c1e936e6a46b
permissions -rw-r--r--
ColName() -> colName(), Coeff() -> coeff()
     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