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