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