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