lemon/graph_reader.h
author deba
Mon, 04 Jul 2005 07:51:57 +0000
changeset 1529 c914e7ec2b7b
parent 1435 8e85e6bbefdf
child 1534 b86aad11f842
permissions -rw-r--r--
Doc repaired
     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       return *this;
   265     }
   266 
   267     /// \brief Add a new attribute reader command.
   268     ///
   269     ///  Add a new attribute reader command.
   270     template <typename Value>
   271     GraphReader& readAttribute(std::string name, Value& value) {
   272       attribute_reader.readAttribute(name, value);
   273       return *this;
   274     }
   275     
   276     /// \brief Add a new attribute reader command.
   277     ///
   278     ///  Add a new attribute reader command.
   279     template <typename Reader, typename Value>
   280     GraphReader& readAttribute(std::string name, Value& value, 
   281 			       const Reader& reader) {
   282       attribute_reader.readAttribute<Reader>(name, value, reader);
   283       return *this;
   284     }
   285 
   286     /// \brief Conversion operator to LemonReader.
   287     ///
   288     /// Conversion operator to LemonReader. It make possible
   289     /// to access the encapsulated \e LemonReader, this way
   290     /// you can attach to this reader new instances of 
   291     /// \e LemonReader::SectionReader.
   292     operator LemonReader&() {
   293       return *reader;
   294     }
   295 
   296     /// \brief Executes the reader commands.
   297     ///
   298     /// Executes the reader commands.
   299     void run() {
   300       reader->run();
   301     }
   302 
   303     /// \brief Gives back the node by its id.
   304     ///
   305     /// It reads an id from the stream and gives back which node belongs to
   306     /// it. It is possible only if there was read an "id" named node map.
   307     Node readId(std::istream& is, Node) const {
   308       return nodeset_reader.readId(is, Node());
   309     } 
   310 
   311     /// \brief Gives back the edge by its id.
   312     ///
   313     /// It reads an id from the stream and gives back which edge belongs to
   314     /// it. It is possible only if there was read an "id" named edge map.
   315     Edge readId(std::istream& is, Edge) const {
   316       return edgeset_reader.readId(is, Edge());
   317     } 
   318 
   319   private:
   320 
   321     LemonReader* reader;
   322     bool own_reader;
   323 
   324     DefaultSkipper skipper;
   325 
   326     NodeSetReader<Graph, ReaderTraits> nodeset_reader;
   327     EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
   328 
   329     NodeReader<Graph> node_reader;
   330     EdgeReader<Graph> edge_reader;
   331     
   332     AttributeReader<ReaderTraits> attribute_reader;
   333   };
   334 
   335   /// \brief Read a graph from the input.
   336   ///
   337   /// Read a graph from the input.
   338   /// \param is The input stream.
   339   /// \param g The graph.
   340   /// \param capacity The capacity map.
   341   /// \param s The source node.
   342   /// \param t The target node.
   343   /// \param cost The cost map.
   344   template<typename Graph, typename CapacityMap, typename CostMap>
   345   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
   346 		  typename Graph::Node &s, typename Graph::Node &t, 
   347 		  CostMap& cost) {
   348     GraphReader<Graph> reader(is, g);
   349     reader.readEdgeMap("capacity", capacity);
   350     reader.readEdgeMap("cost", cost);
   351     reader.readNode("source", s);
   352     reader.readNode("target", t);
   353     reader.run();
   354   }
   355 
   356   /// \brief Read a graph from the input.
   357   ///
   358   /// Read a graph from the input.
   359   /// \param is The input stream.
   360   /// \param g The graph.
   361   /// \param capacity The capacity map.
   362   /// \param s The source node.
   363   /// \param t The target node.
   364   template<typename Graph, typename CapacityMap>
   365   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
   366 		  typename Graph::Node &s, typename Graph::Node &t) {
   367     GraphReader<Graph> reader(is, g);
   368     reader.readEdgeMap("capacity", capacity);
   369     reader.readNode("source", s);
   370     reader.readNode("target", t);
   371     reader.run();
   372   }
   373 
   374   /// \brief Read a graph from the input.
   375   ///
   376   /// Read a graph from the input.
   377   /// \param is The input stream.
   378   /// \param g The graph.
   379   /// \param capacity The capacity map.
   380   /// \param s The source node.
   381   template<typename Graph, typename CapacityMap>
   382   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
   383 		  typename Graph::Node &s) {
   384     GraphReader<Graph> reader(is, g);
   385     reader.readEdgeMap("capacity", capacity);
   386     reader.readNode("source", s);
   387     reader.run();
   388   }
   389 
   390   /// \brief Read a graph from the input.
   391   ///
   392   /// Read a graph from the input.
   393   /// \param is The input stream.
   394   /// \param g The graph.
   395   /// \param capacity The capacity map.
   396   template<typename Graph, typename CapacityMap>
   397   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
   398     GraphReader<Graph> reader(is, g);
   399     reader.readEdgeMap("capacity", capacity);
   400     reader.run();
   401   }
   402 
   403   /// \brief Read a graph from the input.
   404   ///
   405   /// Read a graph from the input.
   406   /// \param is The input stream.
   407   /// \param g The graph.
   408   template<typename Graph>
   409   void readGraph(std::istream& is, Graph &g) {
   410     GraphReader<Graph> reader(is, g);
   411     reader.run();
   412   }
   413 
   414   /// \brief The undir graph reader class.
   415   ///
   416   /// The given file format may contain several maps and labeled nodes or 
   417   /// edges.
   418   ///
   419   /// If you read a graph you need not read all the maps and items just those
   420   /// that you need. The interface of the \c GraphReader is very similar to
   421   /// the GraphWriter but the reading method does not depend on the order the
   422   /// given commands.
   423   ///
   424   /// The reader object suppose that each not readed value does not contain 
   425   /// whitespaces, therefore it has some extra possibilities to control how
   426   /// it should skip the values when the string representation contains spaces.
   427   ///
   428   /// \code
   429   /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
   430   /// \endcode
   431   ///
   432   /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
   433   /// If there is a map that you do not want to read from the file and there is
   434   /// whitespace in the string represenation of the values then you should
   435   /// call the \c skipNodeMap() template member function with proper 
   436   /// parameters.
   437   ///
   438   /// \code
   439   /// reader.readNodeMap("coords", coords);
   440   ///
   441   /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
   442   /// reader.skipNodeMap<QuotedStringReader>("description");
   443   ///
   444   /// reader.readNodeMap("color", colorMap);
   445   /// \endcode
   446   ///
   447   /// With the \c readUndirEdgeMap() member function you can give an 
   448   /// undir edge map reading command similar to the NodeMaps. 
   449   ///
   450   /// \code
   451   /// reader.readUndirEdgeMap("capacity", capacityMap);
   452   /// \endcode
   453   ///
   454   /// The reading of the directed edge maps is just a syntactical sugar.
   455   /// It reads two undirected edgemaps into a directed edge map. The 
   456   /// undirected edge maps' name should be start with the \c '+' and the
   457   /// \c '-' character and the same.
   458   ///
   459   /// \code
   460   /// reader.readEdgeMap("flow", flowMap);
   461   /// \endcode 
   462   ///
   463   /// With \c readNode() and \c readUndirEdge() functions you can read 
   464   /// labeled Nodes and UndirEdges.
   465   ///
   466   /// \code
   467   /// reader.readNode("source", sourceNode);
   468   /// reader.readNode("target", targetNode);
   469   ///
   470   /// reader.readUndirEdge("observed", undirEdge);
   471   /// \endcode
   472   ///
   473   /// With the \c readAttribute() functions you can read an attribute
   474   /// in a variable. You can specify the reader for the attribute as
   475   /// the nodemaps.
   476   ///
   477   /// After you give all read commands you must call the \c run() member
   478   /// function, which execute all the commands.
   479   ///
   480   /// \code
   481   /// reader.run();
   482   /// \endcode
   483   ///
   484   /// \see GraphReader
   485   /// \see DefaultReaderTraits
   486   /// \see \ref UndirGraphWriter
   487   /// \see \ref graph-io-page
   488   ///
   489   /// \author Balazs Dezso
   490   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   491   class UndirGraphReader {
   492   public:
   493     
   494     typedef _Graph Graph;
   495     typedef typename Graph::Node Node;
   496     typedef typename Graph::Edge Edge;
   497     typedef typename Graph::UndirEdge UndirEdge;
   498 
   499     typedef _ReaderTraits ReaderTraits;
   500     typedef typename ReaderTraits::Skipper DefaultSkipper;
   501 
   502     /// \brief Construct a new UndirGraphReader.
   503     ///
   504     /// Construct a new UndirGraphReader. It reads into the given graph
   505     /// and it use the given reader as the default skipper.
   506     UndirGraphReader(std::istream& _is, Graph& _graph, 
   507 		     const DefaultSkipper& _skipper = DefaultSkipper()) 
   508       : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
   509 	nodeset_reader(*reader, _graph, std::string(), skipper),
   510 	undir_edgeset_reader(*reader, _graph, nodeset_reader, 
   511 			     std::string(), skipper),
   512 	node_reader(*reader, nodeset_reader, std::string()),
   513 	undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
   514 	attribute_reader(*reader, std::string()) {}
   515 
   516     /// \brief Construct a new UndirGraphReader.
   517     ///
   518     /// Construct a new UndirGraphReader. It reads into the given graph
   519     /// and it use the given reader as the default skipper.
   520     UndirGraphReader(const std::string& _filename, Graph& _graph, 
   521 		     const DefaultSkipper& _skipper = DefaultSkipper()) 
   522       : reader(new LemonReader(_filename)), own_reader(true), 
   523 	skipper(_skipper),
   524 	nodeset_reader(*reader, _graph, std::string(), skipper),
   525 	undir_edgeset_reader(*reader, _graph, nodeset_reader, 
   526 			     std::string(), skipper),
   527 	node_reader(*reader, nodeset_reader, std::string()),
   528 	undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
   529 	attribute_reader(*reader, std::string()) {}
   530 
   531     /// \brief Construct a new UndirGraphReader.
   532     ///
   533     /// Construct a new UndirGraphReader. It reads into the given graph
   534     /// and it use the given reader as the default skipper.
   535     UndirGraphReader(LemonReader& _reader, Graph& _graph, 
   536 		     const DefaultSkipper& _skipper = DefaultSkipper()) 
   537       : reader(_reader), own_reader(false), skipper(_skipper),
   538 	nodeset_reader(*reader, _graph, std::string(), skipper),
   539 	undir_edgeset_reader(*reader, _graph, nodeset_reader, 
   540 			     std::string(), skipper),
   541 	node_reader(*reader, nodeset_reader, std::string()),
   542 	undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
   543 	attribute_reader(*reader, std::string()) {}
   544 
   545     /// \brief Destruct the graph reader.
   546     ///
   547     /// Destruct the graph reader.
   548     ~UndirGraphReader() {
   549       if (own_reader) 
   550 	delete reader;
   551     }
   552 
   553     /// \brief Add a new node map reader command for the reader.
   554     ///
   555     /// Add a new node map reader command for the reader.
   556     template <typename Map>
   557     UndirGraphReader& readNodeMap(std::string name, Map& map) {
   558       nodeset_reader.readNodeMap(name, map);
   559       return *this;
   560     }
   561 
   562     template <typename Map>
   563     UndirGraphReader& readNodeMap(std::string name, const Map& map) {
   564       nodeset_reader.readNodeMap(name, map);
   565       return *this;
   566     }
   567 
   568     /// \brief Add a new node map reader command for the reader.
   569     ///
   570     /// Add a new node map reader command for the reader.
   571     template <typename Reader, typename Map>
   572     UndirGraphReader& readNodeMap(std::string name, Map& map, 
   573 				  const Reader& reader = Reader()) {
   574       nodeset_reader.readNodeMap(name, map, reader);
   575       return *this;
   576     }
   577 
   578     template <typename Reader, typename Map>
   579     UndirGraphReader& readNodeMap(std::string name, const Map& map, 
   580 				  const Reader& reader = Reader()) {
   581       nodeset_reader.readNodeMap(name, map, reader);
   582       return *this;
   583     }
   584 
   585     /// \brief Add a new node map skipper command for the reader.
   586     ///
   587     /// Add a new node map skipper command for the reader.
   588     template <typename Reader>
   589     UndirGraphReader& skipNodeMap(std::string name, 
   590 			     const Reader& reader = Reader()) {
   591       nodeset_reader.skipNodeMap(name, reader);
   592       return *this;
   593     }
   594 
   595     /// \brief Add a new undirected edge map reader command for the reader.
   596     ///
   597     /// Add a new undirected edge map reader command for the reader.
   598     template <typename Map>
   599     UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) { 
   600       undir_edgeset_reader.readUndirEdgeMap(name, map);
   601       return *this;
   602     }
   603 
   604     template <typename Map>
   605     UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) { 
   606       undir_edgeset_reader.readUndirEdgeMap(name, map);
   607       return *this;
   608     }
   609 
   610 
   611     /// \brief Add a new undirected edge map reader command for the reader.
   612     ///
   613     /// Add a new undirected edge map reader command for the reader.
   614     template <typename Reader, typename Map>
   615     UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
   616 				       const Reader& reader = Reader()) {
   617       undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
   618       return *this;
   619     }
   620 
   621     template <typename Reader, typename Map>
   622     UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
   623 				       const Reader& reader = Reader()) {
   624       undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
   625       return *this;
   626     }
   627 
   628     /// \brief Add a new undirected edge map skipper command for the reader.
   629     ///
   630     /// Add a new undirected edge map skipper command for the reader.
   631     template <typename Reader>
   632     UndirGraphReader& skipUndirEdgeMap(std::string name,
   633 				       const Reader& reader = Reader()) {
   634       undir_edgeset_reader.skipUndirMap(name, reader);
   635       return *this;
   636     }
   637 
   638 
   639     /// \brief Add a new edge map reader command for the reader.
   640     ///
   641     /// Add a new edge map reader command for the reader.
   642     template <typename Map>
   643     UndirGraphReader& readEdgeMap(std::string name, Map& map) { 
   644       undir_edgeset_reader.readEdgeMap(name, map);
   645       return *this;
   646     }
   647 
   648     template <typename Map>
   649     UndirGraphReader& readEdgeMap(std::string name, const Map& map) { 
   650       undir_edgeset_reader.readEdgeMap(name, map);
   651       return *this;
   652     }
   653 
   654 
   655     /// \brief Add a new edge map reader command for the reader.
   656     ///
   657     /// Add a new edge map reader command for the reader.
   658     template <typename Reader, typename Map>
   659     UndirGraphReader& readEdgeMap(std::string name, Map& map,
   660 				       const Reader& reader = Reader()) {
   661       undir_edgeset_reader.readEdgeMap(name, map, reader);
   662       return *this;
   663     }
   664 
   665     template <typename Reader, typename Map>
   666     UndirGraphReader& readEdgeMap(std::string name, const Map& map,
   667 				       const Reader& reader = Reader()) {
   668       undir_edgeset_reader.readEdgeMap(name, map, reader);
   669       return *this;
   670     }
   671 
   672     /// \brief Add a new edge map skipper command for the reader.
   673     ///
   674     /// Add a new edge map skipper command for the reader.
   675     template <typename Reader>
   676     UndirGraphReader& skipEdgeMap(std::string name,
   677 				       const Reader& reader = Reader()) {
   678       undir_edgeset_reader.skipEdgeMap(name, reader);
   679       return *this;
   680     }
   681 
   682     /// \brief Add a new labeled node reader for the reader.
   683     ///
   684     /// Add a new labeled node reader for the reader.
   685     UndirGraphReader& readNode(std::string name, Node& node) {
   686       node_reader.readNode(name, node);
   687       return *this;
   688     }
   689 
   690     /// \brief Add a new labeled edge reader for the reader.
   691     ///
   692     /// Add a new labeled edge reader for the reader.
   693     UndirGraphReader& readEdge(std::string name, Edge& edge) {
   694       undir_edge_reader.readEdge(name, edge);
   695     }
   696 
   697     /// \brief Add a new labeled undirected edge reader for the reader.
   698     ///
   699     /// Add a new labeled undirected edge reader for the reader.
   700     UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
   701       undir_edge_reader.readUndirEdge(name, edge);
   702     }
   703 
   704     /// \brief Add a new attribute reader command.
   705     ///
   706     ///  Add a new attribute reader command.
   707     template <typename Value>
   708     UndirGraphReader& readAttribute(std::string name, Value& value) {
   709       attribute_reader.readAttribute(name, value);
   710       return *this;
   711     }
   712     
   713     /// \brief Add a new attribute reader command.
   714     ///
   715     ///  Add a new attribute reader command.
   716     template <typename Reader, typename Value>
   717     UndirGraphReader& readAttribute(std::string name, Value& value, 
   718 			       const Reader& reader) {
   719       attribute_reader.readAttribute<Reader>(name, value, reader);
   720       return *this;
   721     }
   722 
   723     /// \brief Conversion operator to LemonReader.
   724     ///
   725     /// Conversion operator to LemonReader. It make possible
   726     /// to access the encapsulated \e LemonReader, this way
   727     /// you can attach to this reader new instances of 
   728     /// \e LemonReader::SectionReader.
   729     operator LemonReader&() {
   730       return *reader;
   731     }
   732 
   733     /// \brief Executes the reader commands.
   734     ///
   735     /// Executes the reader commands.
   736     void run() {
   737       reader->run();
   738     }
   739 
   740     /// \brief Gives back the node by its id.
   741     ///
   742     /// It reads an id from the stream and gives back which node belongs to
   743     /// it. It is possible only if there was read an "id" named node map.
   744     Node readId(std::istream& is, Node) const {
   745       return nodeset_reader.readId(is, Node());
   746     } 
   747 
   748     /// \brief Gives back the edge by its id.
   749     ///
   750     /// It reads an id from the stream and gives back which edge belongs to
   751     /// it. It is possible only if there was read an "id" named edge map.
   752     Edge readId(std::istream& is, Edge) const {
   753       return undir_edgeset_reader.readId(is, Edge());
   754     } 
   755 
   756     /// \brief Gives back the undirected edge by its id.
   757     ///
   758     /// It reads an id from the stream and gives back which undirected edge 
   759     /// belongs to it. It is possible only if there was read an "id" named 
   760     /// edge map.
   761     UndirEdge readId(std::istream& is, UndirEdge) const {
   762       return undir_edgeset_reader.readId(is, UndirEdge());
   763     } 
   764     
   765 
   766   private:
   767 
   768     LemonReader* reader;
   769     bool own_reader;
   770 
   771     DefaultSkipper skipper;
   772 
   773     NodeSetReader<Graph, ReaderTraits> nodeset_reader;
   774     UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
   775 
   776     NodeReader<Graph> node_reader;
   777     UndirEdgeReader<Graph> undir_edge_reader;
   778     
   779     AttributeReader<ReaderTraits> attribute_reader;
   780   };
   781 
   782   /// \brief Read an undir graph from the input.
   783   ///
   784   /// Read an undir graph from the input.
   785   /// \param is The input stream.
   786   /// \param g The graph.
   787   /// \param capacity The capacity map.
   788   template<typename Graph, typename CapacityMap>
   789   void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
   790     UndirGraphReader<Graph> reader(is, g);
   791     reader.readUndirEdgeMap("capacity", capacity);
   792     reader.run();
   793   }
   794 
   795   /// \brief Read an undir graph from the input.
   796   ///
   797   /// Read an undir graph from the input.
   798   /// \param is The input stream.
   799   /// \param g The graph.
   800   template<typename Graph>
   801   void readUndirGraph(std::istream& is, Graph &g) {
   802     UndirGraphReader<Graph> reader(is, g);
   803     reader.run();
   804   }
   805 
   806   /// @}
   807 }
   808 
   809 #endif