lemon/graph_reader.h
author deba
Mon, 12 Sep 2005 11:24:54 +0000
changeset 1681 84e43c7ca1e3
parent 1534 b86aad11f842
child 1705 3f63d9db307b
permissions -rw-r--r--
SubGraphAdaptors with edge checking functionality.

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