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