src/lemon/graph_reader.h
author deba
Thu, 28 Apr 2005 09:54:38 +0000
changeset 1396 56f9a4ba9149
parent 1394 f0c48d7fa73d
child 1408 892c29484414
permissions -rw-r--r--
GUI section handling.
     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 #include <sstream>
    26 
    27 #include <map>
    28 #include <vector>
    29 
    30 #include <memory>
    31 
    32 #include <lemon/error.h>
    33 
    34 
    35 namespace lemon {
    36 
    37   /// \addtogroup io_group
    38   /// @{
    39 
    40   /// \brief Standard ReaderTraits for the GraphReader class.
    41   ///
    42   /// Standard ReaderTraits for the GraphReader class.
    43   /// It defines standard reading method for all type of value. 
    44   /// \author Balazs Dezso
    45   struct DefaultReaderTraits {
    46 
    47     /// \brief Template class for reading an value.
    48     ///
    49     /// Template class for reading an value.
    50     /// \author Balazs Dezso
    51     template <typename _Value>
    52     struct Reader {
    53       /// The value type.
    54       typedef _Value Value;
    55       /// \brief Reads a value from the given stream.
    56       ///
    57       /// Reads a value from the given stream.
    58       void read(std::istream& is, Value& value) {
    59 	if (!(is >> value)) 
    60 	  throw DataFormatError("Default reader format exception");
    61       }
    62     };
    63 
    64     /// \brief Returns wheter this name is an ID map name.
    65     ///
    66     /// Returns wheter this name is an ID map name.
    67     static bool idMapName(const std::string& name) {
    68       return name == "id";
    69     }
    70 
    71     /// The reader class for the not needed maps.
    72     typedef Reader<std::string> DefaultReader;
    73 
    74   };
    75 
    76   /// \brief Reader class for quoted strings.
    77   ///
    78   /// Reader class for quoted strings. It can process the escape
    79   /// sequences in the string.
    80   /// \author Balazs Dezso
    81   class QuotedStringReader {
    82   public:
    83     typedef std::string Value;
    84     
    85     /// \brief Constructor for the reader.
    86     ///
    87     /// Constructor for the reader. If the given parameter is true
    88     /// the reader processes the escape sequences.
    89     QuotedStringReader(bool _escaped = true) : escaped(_escaped) {}
    90     
    91     /// \brief Reads a quoted string from the given stream.
    92     ///
    93     /// Reads a quoted string from the given stream.
    94     void read(std::istream& is, std::string& value) {
    95       char c;
    96       value.clear();
    97       is >> std::ws;
    98       if (!is.get(c) || c != '\"') 
    99 	throw DataFormatError("Quoted string format error");
   100       while (is.get(c) && c != '\"') {
   101 	if (escaped && c == '\\') {
   102 	  value += readEscape(is);
   103 	} else {
   104 	  value += c;
   105 	}
   106       }
   107       if (!is) throw DataFormatError("Quoted string format error");
   108     }
   109 
   110   private:
   111     
   112     static char readEscape(std::istream& is) {
   113       char c;
   114       switch (is.get(c), c) {
   115       case '\\':
   116 	return '\\';
   117       case '\"':
   118 	return '\"';
   119       case '\'':
   120 	return '\'';
   121       case '\?':
   122 	return '\?';
   123       case 'a':
   124 	return '\a';
   125       case 'b':
   126 	return '\b';
   127       case 'f':
   128 	return '\f';
   129       case 'n':
   130 	return '\n';
   131       case 'r':
   132 	return '\r';
   133       case 't':
   134 	return '\t';
   135       case 'v':
   136 	return '\v';
   137       case 'x':
   138 	{
   139 	  int code;
   140 	  if (!is.get(c) || !isHex(c)) 
   141 	    throw DataFormatError("Escape format error");
   142 	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
   143 	  else code = code * 16 + valueHex(c);
   144 	  return code;
   145 	}
   146       default:
   147 	{
   148 	  int code;
   149 	  if (!isOct(c)) 
   150 	    throw DataFormatError("Escape format error");
   151 	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
   152 	    is.putback(c);
   153 	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
   154 	    is.putback(c);
   155 	  else code = code * 8 + valueOct(c);
   156 	  return code;
   157 	}	      
   158       } 
   159     }
   160 
   161     static bool isOct(char c) {
   162       return '0' <= c && c <='7'; 
   163     }
   164     
   165     static int valueOct(char c) {
   166       return c - '0';
   167     }
   168 
   169    static bool isHex(char c) {
   170       return ('0' <= c && c <= '9') || 
   171 	('a' <= c && c <= 'z') || 
   172 	('A' <= c && c <= 'Z'); 
   173     }
   174     
   175     static int valueHex(char c) {
   176       if ('0' <= c && c <= '9') return c - '0';
   177       if ('a' <= c && c <= 'z') return c - 'a' + 10;
   178       return c - 'A' + 10;
   179     }
   180 
   181     bool escaped;
   182   };
   183 
   184   class GUIReader {
   185   public:
   186     virtual void read(std::istream& is) = 0;
   187   };
   188 
   189   /// \brief The graph reader class.
   190   ///
   191   ///
   192   /// The given file format may contain several maps and labeled nodes or 
   193   /// edges.
   194   ///
   195   /// If you read a graph you need not read all the maps and items just those
   196   /// that you need. The interface of the \c GraphReader is very similar to
   197   /// the GraphWriter but the reading method does not depend on the order the
   198   /// given commands.
   199   ///
   200   /// The reader object suppose that each not readed value does not contain 
   201   /// whitespaces, therefore it has some extra possibilities to control how
   202   /// it should skip the values when the string representation contains spaces.
   203   ///
   204   /// \code
   205   /// GraphReader<ListGraph> reader(std::cin, graph);
   206   /// \endcode
   207   ///
   208   /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
   209   /// If there is a map that you do not want to read from the file and there is
   210   /// whitespace in the string represenation of the values then you should
   211   /// call the \c skipNodeMap() template member function with proper 
   212   /// parameters.
   213   ///
   214   /// \code
   215   /// reader.readNodeMap("x-coord", xCoordMap);
   216   /// reader.readNodeMap("y-coord", yCoordMap);
   217   ///
   218   /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
   219   /// reader.skipNodeMap<QuotedStringReader>("description");
   220   ///
   221   /// reader.readNodeMap("color", colorMap);
   222   /// \endcode
   223   ///
   224   /// With the \c readEdgeMap() member function you can give an edge map
   225   /// reading command similar to the NodeMaps. 
   226   ///
   227   /// \code
   228   /// reader.readEdgeMap("weight", weightMap);
   229   /// reader.readEdgeMap("label", labelMap);
   230   /// \endcode
   231   ///
   232   /// With \c readNode() and \c readEdge() functions you can read labeled Nodes 
   233   /// and Edges.
   234   ///
   235   /// \code
   236   /// reader.readNode("source", sourceNode);
   237   /// reader.readNode("target", targetNode);
   238   ///
   239   /// reader.readEdge("observed", edge);
   240   /// \endcode
   241   ///
   242   /// After you give all read commands you must call the \c run() member
   243   /// function, which execute all the commands.
   244   ///
   245   /// \code
   246   /// reader.run();
   247   /// \endcode
   248   ///
   249   /// \see DefaultReaderTraits
   250   /// \see QuotedStringReader
   251   /// \see \ref GraphWriter
   252   /// \see \ref graph-io-page
   253   /// \author Balazs Dezso
   254   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   255   class GraphReader {
   256   public:
   257     
   258     typedef _Graph Graph;
   259     typedef typename Graph::Node Node;
   260     typedef typename Graph::Edge Edge;
   261 
   262     typedef _ReaderTraits ReaderTraits;
   263     typedef typename ReaderTraits::DefaultReader DefaultReader;
   264 
   265     /// \brief Construct a new GraphReader.
   266     ///
   267     /// Construct a new GraphReader. It reads into the given graph
   268     /// and it use the given reader as the default skipper.
   269     GraphReader(std::istream& _is, Graph& _graph, 
   270 		const DefaultReader& _reader = DefaultReader()) 
   271       : gui_reader(0), is(_is), graph(_graph), 
   272 	nodeSkipper(_reader), edgeSkipper(_reader) {}
   273 
   274     /// \brief Destruct the graph reader.
   275     ///
   276     /// Destruct the graph reader.
   277     ~GraphReader() {
   278       for (typename NodeMapReaders::iterator it = node_map_readers.begin(); 
   279 	   it != node_map_readers.end(); ++it) {
   280 	delete it->second;
   281       }
   282 
   283       for (typename EdgeMapReaders::iterator it = edge_map_readers.begin(); 
   284 	   it != edge_map_readers.end(); ++it) {
   285 	delete it->second;
   286       }
   287 
   288     }
   289 
   290     /// \brief Add a new node map reader command for the reader.
   291     ///
   292     /// Add a new node map reader command for the reader.
   293     template <typename Map>
   294     GraphReader& readNodeMap(std::string name, Map& map) {
   295       return readNodeMap<typename ReaderTraits::template 
   296 	Reader<typename Map::Value>, Map>(name, map);
   297     }
   298 
   299     /// \brief Add a new node map reader command for the reader.
   300     ///
   301     /// Add a new node map reader command for the reader.
   302     template <typename Reader, typename Map>
   303     GraphReader& readNodeMap(std::string name, Map& map, 
   304 			     const Reader& reader = Reader()) {
   305       if (node_map_readers.find(name) != node_map_readers.end()) {
   306 	ErrorMessage msg;
   307 	msg << "Multiple read rule for node map: " << name;
   308 	throw IOParameterError(msg.message());
   309       }
   310       node_map_readers.insert(
   311         make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
   312       return *this;
   313     }
   314 
   315     /// \brief Add a new node map skipper command for the reader.
   316     ///
   317     /// Add a new node map skipper command for the reader.
   318     template <typename Reader>
   319     GraphReader& skipNodeMap(std::string name, 
   320 			     const Reader& reader = Reader()) {
   321       if (node_map_readers.find(name) != node_map_readers.end()) {
   322 	ErrorMessage msg;
   323 	msg << "Multiple read rule for node map: " << name;
   324 	throw IOParameterError(msg.message());
   325       }
   326       node_map_readers.insert(
   327         make_pair(name, new SkipReader<Node, Reader>(reader)));
   328       return *this;
   329     }
   330 
   331     /// \brief Add a new edge map reader command for the reader.
   332     ///
   333     /// Add a new edge map reader command for the reader.
   334     template <typename Map>
   335     GraphReader& readEdgeMap(std::string name, Map& map) { 
   336       return readEdgeMap<typename ReaderTraits::template
   337 	Reader<typename Map::Value>, Map>(name, map);
   338     }
   339 
   340 
   341     /// \brief Add a new edge map reader command for the reader.
   342     ///
   343     /// Add a new edge map reader command for the reader.
   344     template <typename Reader, typename Map>
   345     GraphReader& readEdgeMap(std::string name, Map& map,
   346 			     const Reader& reader = Reader()) {
   347       if (edge_map_readers.find(name) != edge_map_readers.end()) {
   348 	ErrorMessage msg;
   349 	msg << "Multiple read rule for edge map: " << name;
   350 	throw IOParameterError(msg.message());
   351       }
   352       edge_map_readers.insert(
   353         make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   354       return *this;
   355     }
   356 
   357     /// \brief Add a new edge map skipper command for the reader.
   358     ///
   359     /// Add a new edge map skipper command for the reader.
   360     template <typename Reader>
   361     GraphReader& skipEdgeMap(std::string name,
   362 			     const Reader& reader = Reader()) {
   363       if (edge_map_readers.find(name) != edge_map_readers.end()) {
   364 	ErrorMessage msg;
   365 	msg << "Multiple read rule for edge map: " << name;
   366 	throw IOParameterError(msg.message());
   367       }
   368       edge_map_readers.insert(
   369         make_pair(name, new SkipReader<Edge, Reader>(reader)));
   370       return *this;
   371     }
   372 
   373     /// \brief Add a new labeled node reader for the reader.
   374     ///
   375     /// Add a new labeled node reader for the reader.
   376     GraphReader& readNode(std::string name, Node& node) {
   377       if (node_readers.find(name) != node_readers.end()) {
   378 	ErrorMessage msg;
   379 	msg << "Multiple read rule for node: " << name;
   380 	throw IOParameterError(msg.message());
   381       }
   382       node_readers.insert(make_pair(name, &node));
   383       return *this;
   384     }
   385 
   386     /// \brief Add a new labeled edge reader for the reader.
   387     ///
   388     /// Add a new labeled edge reader for the reader.
   389     GraphReader& readEdge(std::string name, Edge& edge) {
   390       if (edge_readers.find(name) != edge_readers.end()) {
   391 	ErrorMessage msg;
   392 	msg << "Multiple read rule for edge: " << name;
   393 	throw IOParameterError(msg.message());
   394       }
   395       edge_readers.insert(make_pair(name, &edge));
   396       return *this;
   397     }
   398 
   399     /// \brief Executes the reader commands.
   400     ///
   401     /// Executes the reader commands.
   402     void run() {
   403       int line_num = 0;
   404       std::auto_ptr<InverterBase<Node> > nodeInverter;
   405       std::auto_ptr<InverterBase<Edge> > edgeInverter;
   406       try {
   407 	std::string line = readNotEmptyLine(is, line_num);
   408 	if (line.find("@nodeset") == 0) {
   409 	  line = readNodeSet(line_num, nodeInverter);
   410 	} 
   411 	if (line.find("@edgeset") == 0) {
   412 	  line = readEdgeSet(line_num, edgeInverter, nodeInverter);
   413 	}
   414 	if (line.find("@nodes") == 0) {
   415 	  line = readNodes(line_num, nodeInverter);
   416 	}
   417 	if (line.find("@edges") == 0) {
   418 	  line = readEdges(line_num, edgeInverter);
   419 	}
   420 	if (line.find("@gui") == 0) {
   421 	  line = readGUI(line_num);
   422 	}
   423 	if (line.find("@end") != 0) {
   424 	  throw DataFormatError("Invalid control sequence error");
   425 	}
   426       } catch (DataFormatError e) {
   427 	e.line(line_num);
   428 	throw e;
   429       }
   430     }
   431 
   432     GraphReader& readGUI(GUIReader& reader) {
   433       gui_reader = &reader;
   434       return *this;
   435     }
   436 
   437   private:
   438 
   439     template <typename Item> class InverterBase;
   440 
   441     std::string readNodeSet(int& line_num, 
   442 			    std::auto_ptr<InverterBase<Node> >& nodeInverter) {
   443       std::vector<ReaderBase<Node>* > index;
   444       {
   445 	std::string line = readNotEmptyLine(is, line_num);    
   446 	std::string id;
   447 	std::istringstream ls(line);	
   448 	while (ls >> id) {
   449 	  typename NodeMapReaders::iterator it = node_map_readers.find(id);
   450 	  if (it != node_map_readers.end()) {
   451 	    index.push_back(it->second);
   452 	    node_map_readers.erase(it);
   453 	  } else {
   454 	    index.push_back(&nodeSkipper);
   455 	  }
   456 	  if (ReaderTraits::idMapName(id) && nodeInverter.get() == 0) {
   457 	    nodeInverter.reset(index.back()->getInverter());
   458 	    index.back() = nodeInverter.get();
   459 	  }
   460 	}
   461       }
   462 
   463 //       if (index.size() == 0) {
   464 // 	throw DataFormatError("Cannot find node id map");
   465 //       }
   466 
   467 //       nodeInverter = 
   468 // 	std::auto_ptr<InverterBase<Node> >(index[0]->getInverter());
   469       std::string line;
   470       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   471 	Node node = graph.addNode();
   472 	std::istringstream ls(line);
   473 	for (int i = 0; i < (int)index.size(); ++i) {
   474 	  index[i]->read(ls, node);
   475 	}
   476       }
   477       return line;
   478     }
   479 
   480     std::string readEdgeSet(int& line_num, 
   481 			    std::auto_ptr<InverterBase<Edge> >& edgeInverter, 
   482 			    std::auto_ptr<InverterBase<Node> >& nodeInverter) {
   483       std::vector<ReaderBase<Edge>*> index;
   484       {
   485 	std::string line = readNotEmptyLine(is, line_num);    
   486 	std::string id;
   487 	std::istringstream ls(line);	
   488 	while (ls >> id) {
   489 	  typename EdgeMapReaders::iterator it = edge_map_readers.find(id);
   490 	  if (it != edge_map_readers.end()) {
   491 	    index.push_back(it->second);
   492 	    edge_map_readers.erase(it);
   493 	  } else {
   494 	    index.push_back(&edgeSkipper);
   495 	  }
   496 	  if (ReaderTraits::idMapName(id) && edgeInverter.get() == 0) {
   497 	    edgeInverter.reset(index.back()->getInverter());
   498 	    index.back() = edgeInverter.get();
   499 	  }
   500 	}
   501       }
   502       
   503       if (nodeInverter.get() == 0) {
   504  	throw DataFormatError("Cannot find node id map");
   505       }
   506 //       if (index.size() == 0) {
   507 // 	throw DataFormatError("Cannot find edge id map");
   508 //       }
   509 
   510 //       edgeInverter = 
   511 // 	std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
   512       std::string line;
   513       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	
   514 	std::istringstream ls(line);
   515 	Node source = nodeInverter->read(ls);
   516 	Node target = nodeInverter->read(ls);
   517 	Edge edge = graph.addEdge(source, target);
   518 	for (int i = 0; i < (int)index.size(); ++i) {
   519 	  index[i]->read(ls, edge);
   520 	}
   521       }      
   522       return line;
   523     }
   524 
   525     std::string readNodes(int& line_num, 
   526 			  std::auto_ptr<InverterBase<Node> >& nodeInverter) {
   527       std::string line;
   528       if (nodeInverter.get() == 0) {
   529  	throw DataFormatError("Cannot find node id map");
   530       }
   531       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   532 	std::istringstream ls(line);
   533 	std::string name;
   534 	ls >> name;
   535 	typename NodeReaders::iterator it = node_readers.find(name);
   536 	if (it != node_readers.end()) {
   537 	  *(it -> second) = nodeInverter->read(ls);
   538 	} 
   539       }        
   540       return line;
   541     }
   542 
   543     std::string readEdges(int& line_num, 
   544 			  std::auto_ptr<InverterBase<Edge> >& edgeInverter) {
   545       std::string line;
   546       if (edgeInverter.get() == 0) {
   547  	throw DataFormatError("Cannot find edge id map");
   548       }
   549       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   550 	std::istringstream ls(line);
   551 	std::string name;
   552 	ls >> name;
   553 	typename EdgeReaders::iterator it = edge_readers.find(name);
   554 	if (it != edge_readers.end()) {
   555 	  *(it -> second) = edgeInverter->read(ls);
   556 	} 
   557       }        
   558       return line;    
   559     }
   560 
   561     std::string readGUI(int& line_num) {
   562       std::stringstream section;
   563       std::string line;
   564       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   565 	section << line << std::endl;
   566       }
   567       if (gui_reader != 0) {
   568 	gui_reader->read(section);
   569       }
   570       return line;
   571     }
   572 
   573     std::string readNotEmptyLine(std::istream& is, int& line_num) {
   574       std::string line;
   575       while (++line_num, getline(is, line)) {	
   576 	int vi = line.find('#');
   577 	if (vi != (int)::std::string::npos) {
   578 	  line = line.substr(0, vi);
   579 	}
   580 	vi = line.find_first_not_of(" \t");
   581 	if (vi != (int)std::string::npos) { 
   582 	  return line.substr(vi);
   583 	}
   584       }
   585       throw DataFormatError("End of stream error");
   586     }
   587     
   588     template <typename _Item>
   589     class ReaderBase;
   590     
   591     template <typename _Item>
   592     class InverterBase : public ReaderBase<_Item> {
   593     public:
   594       typedef _Item Item;
   595       virtual void read(std::istream&, const Item&) = 0;
   596       virtual Item read(std::istream&) = 0;
   597 
   598       virtual InverterBase<_Item>* getInverter() {
   599 	return this;
   600       }
   601     };
   602 
   603     template <typename _Item, typename _Map, typename _Reader>
   604     class MapReaderInverter : public InverterBase<_Item> {
   605     public:
   606       typedef _Item Item;
   607       typedef _Reader Reader;
   608       typedef typename Reader::Value Value;
   609       typedef _Map Map;
   610       typedef std::map<Value, Item> Inverse;
   611 
   612       Map& map;
   613       Reader reader;
   614       Inverse inverse;
   615 
   616       MapReaderInverter(Map& _map, const Reader& _reader) 
   617 	: map(_map), reader(_reader) {}
   618 
   619       virtual ~MapReaderInverter() {}
   620 
   621       virtual void read(std::istream& is, const Item& item) {
   622 	Value value;
   623 	reader.read(is, value);
   624 	map.set(item, value);
   625 	typename Inverse::iterator it = inverse.find(value);
   626 	if (it == inverse.end()) {
   627 	  inverse.insert(std::make_pair(value, item));
   628 	} else {
   629 	  throw DataFormatError("Multiple ID occurence");
   630 	}
   631       }
   632 
   633       virtual Item read(std::istream& is) {
   634 	Value value;
   635 	reader.read(is, value);	
   636 	typename Inverse::const_iterator it = inverse.find(value);
   637 	if (it != inverse.end()) {
   638 	  return it->second;
   639 	} else {
   640 	  throw DataFormatError("Invalid ID error");
   641 	}
   642       }      
   643     };
   644 
   645     template <typename _Item, typename _Reader>
   646     class SkipReaderInverter : public InverterBase<_Item> {
   647     public:
   648       typedef _Item Item;
   649       typedef _Reader Reader;
   650       typedef typename Reader::Value Value;
   651       typedef std::map<Value, Item> Inverse;
   652 
   653       Reader reader;
   654 
   655       SkipReaderInverter(const Reader& _reader) 
   656 	: reader(_reader) {}
   657 
   658       virtual ~SkipReaderInverter() {}
   659 
   660       virtual void read(std::istream& is, const Item& item) {
   661 	Value value;
   662 	reader.read(is, value);
   663 	typename Inverse::iterator it = inverse.find(value);
   664 	if (it == inverse.end()) {
   665 	  inverse.insert(std::make_pair(value, item));
   666 	} else {
   667 	  throw DataFormatError("Multiple ID occurence error");
   668 	}
   669       }
   670 
   671       virtual Item read(std::istream& is) {
   672 	Value value;
   673 	reader.read(is, value);	
   674 	typename Inverse::const_iterator it = inverse.find(value);
   675 	if (it != inverse.end()) {
   676 	  return it->second;
   677 	} else {
   678 	  throw DataFormatError("Invalid ID error");
   679 	}
   680       }      
   681     private:
   682       Inverse inverse;
   683     };
   684 
   685     // Readers
   686 
   687     template <typename _Item>    
   688     class ReaderBase {
   689     public:
   690       typedef _Item Item;
   691 
   692       //      virtual ~ReaderBase() {}
   693 
   694       virtual void read(std::istream& is, const Item& item) = 0;
   695       virtual InverterBase<_Item>* getInverter() = 0;
   696     };
   697 
   698     template <typename _Item, typename _Map, typename _Reader>
   699     class MapReader : public ReaderBase<_Item> {
   700     public:
   701       typedef _Map Map;
   702       typedef _Reader Reader;
   703       typedef typename Reader::Value Value;
   704       typedef _Item Item;
   705       
   706       Map& map;
   707       Reader reader;
   708 
   709       MapReader(Map& _map, const Reader& _reader) 
   710 	: map(_map), reader(_reader) {}
   711 
   712       virtual ~MapReader() {}
   713 
   714       virtual void read(std::istream& is, const Item& item) {
   715 	Value value;
   716 	reader.read(is, value);
   717 	map.set(item, value);
   718       }
   719 
   720       virtual InverterBase<_Item>* getInverter() {
   721 	return new MapReaderInverter<Item, Map, Reader>(map, reader);
   722       }
   723     };
   724 
   725 
   726     template <typename _Item, typename _Reader>
   727     class SkipReader : public ReaderBase<_Item> {
   728     public:
   729       typedef _Reader Reader;
   730       typedef typename Reader::Value Value;
   731       typedef _Item Item;
   732 
   733       Reader reader;
   734       SkipReader(const Reader& _reader) : reader(_reader) {}
   735 
   736       virtual ~SkipReader() {}
   737 
   738       virtual void read(std::istream& is, const Item&) {
   739 	Value value;
   740 	reader.read(is, value);
   741       }      
   742 
   743       virtual InverterBase<Item>* getInverter() {
   744 	return new SkipReaderInverter<Item, Reader>(reader);
   745       }
   746     };
   747 
   748 
   749     typedef std::map<std::string, ReaderBase<Node>*> NodeMapReaders;
   750     NodeMapReaders node_map_readers;
   751 
   752     typedef std::map<std::string, ReaderBase<Edge>*> EdgeMapReaders;
   753     EdgeMapReaders edge_map_readers;
   754 
   755     typedef std::map<std::string, Node*> NodeReaders;
   756     NodeReaders node_readers;
   757 
   758     typedef std::map<std::string, Edge*> EdgeReaders;
   759     EdgeReaders edge_readers;
   760 
   761     GUIReader* gui_reader;
   762 
   763     std::istream& is;
   764     Graph& graph;
   765 
   766     SkipReader<Node, DefaultReader> nodeSkipper;
   767     SkipReader<Edge, DefaultReader> edgeSkipper;
   768 
   769   };
   770 
   771   /// \brief Read a graph from the input.
   772   ///
   773   /// Read a graph from the input.
   774   /// \param is The input stream.
   775   /// \param g The graph.
   776   /// \param capacity The capacity map.
   777   /// \param s The source node.
   778   /// \param t The target node.
   779   /// \param cost The cost map.
   780   template<typename Graph, typename CapacityMap, typename CostMap>
   781   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
   782 		  typename Graph::Node &s, typename Graph::Node &t, 
   783 		  CostMap& cost) {
   784     GraphReader<Graph> reader(is, g);
   785     reader.readEdgeMap("capacity", capacity);
   786     reader.readEdgeMap("cost", cost);
   787     reader.readNode("source", s);
   788     reader.readNode("target", t);
   789     reader.run();
   790   }
   791 
   792   /// \brief Read a graph from the input.
   793   ///
   794   /// Read a graph from the input.
   795   /// \param is The input stream.
   796   /// \param g The graph.
   797   /// \param capacity The capacity map.
   798   /// \param s The source node.
   799   /// \param t The target node.
   800   template<typename Graph, typename CapacityMap>
   801   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
   802 		  typename Graph::Node &s, typename Graph::Node &t) {
   803     GraphReader<Graph> reader(is, g);
   804     reader.readEdgeMap("capacity", capacity);
   805     reader.readNode("source", s);
   806     reader.readNode("target", t);
   807     reader.run();
   808   }
   809 
   810   /// \brief Read a graph from the input.
   811   ///
   812   /// Read a graph from the input.
   813   /// \param is The input stream.
   814   /// \param g The graph.
   815   /// \param capacity The capacity map.
   816   /// \param s The source node.
   817   template<typename Graph, typename CapacityMap>
   818   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
   819 		  typename Graph::Node &s) {
   820     GraphReader<Graph> reader(is, g);
   821     reader.readEdgeMap("capacity", capacity);
   822     reader.readNode("source", s);
   823     reader.run();
   824   }
   825 
   826   /// \brief Read a graph from the input.
   827   ///
   828   /// Read a graph from the input.
   829   /// \param is The input stream.
   830   /// \param g The graph.
   831   /// \param capacity The capacity map.
   832   template<typename Graph, typename CapacityMap>
   833   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
   834     GraphReader<Graph> reader(is, g);
   835     reader.readEdgeMap("capacity", capacity);
   836     reader.run();
   837   }
   838 
   839   /// \brief Read a graph from the input.
   840   ///
   841   /// Read a graph from the input.
   842   /// \param is The input stream.
   843   /// \param g The graph.
   844   template<typename Graph>
   845   void readGraph(std::istream& is, Graph &g) {
   846     GraphReader<Graph> reader(is, g);
   847     reader.run();
   848   }
   849 
   850   /// @}
   851 }
   852 
   853 #endif