lemon/lgf_reader.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 03 Jul 2008 12:40:04 +0200
changeset 188 70694e6bdcac
parent 186 9159de5e9657
child 189 a63ed81c57ba
permissions -rw-r--r--
New skip*() functions in (Dig|G)raphReader
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2008
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 ///\ingroup lemon_io
    20 ///\file
    21 ///\brief Lemon Graph Format reader.
    22 
    23 
    24 #ifndef LEMON_LGF_READER_H
    25 #define LEMON_LGF_READER_H
    26 
    27 #include <iostream>
    28 #include <fstream>
    29 #include <sstream>
    30 
    31 #include <set>
    32 #include <map>
    33 
    34 #include <lemon/assert.h>
    35 #include <lemon/graph_utils.h>
    36 
    37 #include <lemon/lgf_writer.h>
    38 
    39 #include <lemon/concept_check.h>
    40 #include <lemon/concepts/maps.h>
    41 
    42 namespace lemon {
    43 
    44   namespace _reader_bits {
    45 
    46     template <typename Value>
    47     struct DefaultConverter {
    48       Value operator()(const std::string& str) {
    49 	std::istringstream is(str);
    50 	Value value;
    51 	is >> value;
    52 
    53 	char c;
    54 	if (is >> std::ws >> c) {
    55 	  throw DataFormatError("Remaining characters in token");
    56 	}
    57 	return value;
    58       }
    59     };
    60 
    61     template <>
    62     struct DefaultConverter<std::string> {
    63       std::string operator()(const std::string& str) {
    64 	return str;
    65       }
    66     };
    67 
    68     template <typename _Item>    
    69     class MapStorageBase {
    70     public:
    71       typedef _Item Item;
    72 
    73     public:
    74       MapStorageBase() {}
    75       virtual ~MapStorageBase() {}
    76 
    77       virtual void set(const Item& item, const std::string& value) = 0;
    78 
    79     };
    80 
    81     template <typename _Item, typename _Map, 
    82 	      typename _Converter = DefaultConverter<typename _Map::Value> >
    83     class MapStorage : public MapStorageBase<_Item> {
    84     public:
    85       typedef _Map Map;
    86       typedef _Converter Converter;
    87       typedef _Item Item;
    88       
    89     private:
    90       Map& _map;
    91       Converter _converter;
    92 
    93     public:
    94       MapStorage(Map& map, const Converter& converter = Converter()) 
    95 	: _map(map), _converter(converter) {}
    96       virtual ~MapStorage() {}
    97 
    98       virtual void set(const Item& item ,const std::string& value) {
    99 	_map.set(item, _converter(value));
   100       }
   101     };
   102 
   103     template <typename _Graph, bool _dir, typename _Map, 
   104 	      typename _Converter = DefaultConverter<typename _Map::Value> >
   105     class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
   106     public:
   107       typedef _Map Map;
   108       typedef _Converter Converter;
   109       typedef _Graph Graph;
   110       typedef typename Graph::Edge Item;
   111       static const bool dir = _dir;
   112       
   113     private:
   114       const Graph& _graph;
   115       Map& _map;
   116       Converter _converter;
   117 
   118     public:
   119       GraphArcMapStorage(const Graph& graph, Map& map, 
   120 			 const Converter& converter = Converter()) 
   121 	: _graph(graph), _map(map), _converter(converter) {}
   122       virtual ~GraphArcMapStorage() {}
   123 
   124       virtual void set(const Item& item ,const std::string& value) {
   125 	_map.set(_graph.direct(item, dir), _converter(value));
   126       }
   127     };
   128 
   129     class ValueStorageBase {
   130     public:
   131       ValueStorageBase() {}
   132       virtual ~ValueStorageBase() {}
   133 
   134       virtual void set(const std::string&) = 0;
   135     };
   136 
   137     template <typename _Value, typename _Converter = DefaultConverter<_Value> >
   138     class ValueStorage : public ValueStorageBase {
   139     public:
   140       typedef _Value Value;
   141       typedef _Converter Converter;
   142 
   143     private:
   144       Value& _value;
   145       Converter _converter;
   146 
   147     public:
   148       ValueStorage(Value& value, const Converter& converter = Converter())
   149  	: _value(value), _converter(converter) {}
   150 
   151       virtual void set(const std::string& value) {
   152 	_value = _converter(value);
   153       }
   154     };
   155 
   156     template <typename Value>
   157     struct MapLookUpConverter {
   158       const std::map<std::string, Value>& _map;
   159 
   160       MapLookUpConverter(const std::map<std::string, Value>& map)
   161         : _map(map) {}
   162 
   163       Value operator()(const std::string& str) {
   164         typename std::map<std::string, Value>::const_iterator it =
   165           _map.find(str);
   166         if (it == _map.end()) {
   167           std::ostringstream msg;
   168           msg << "Item not found: " << str;
   169           throw DataFormatError(msg.str().c_str());
   170         }
   171         return it->second;
   172       }
   173     };
   174 
   175     template <typename Graph>
   176     struct GraphArcLookUpConverter {
   177       const Graph& _graph;
   178       const std::map<std::string, typename Graph::Edge>& _map;
   179       
   180       GraphArcLookUpConverter(const Graph& graph, 
   181 			      const std::map<std::string,
   182 			                     typename Graph::Edge>& map) 
   183 	: _graph(graph), _map(map) {}
   184       
   185       typename Graph::Arc operator()(const std::string& str) {
   186 	if (str.empty() || (str[0] != '+' && str[0] != '-')) {
   187 	  throw DataFormatError("Item must start with '+' or '-'");
   188 	}
   189 	typename std::map<std::string, typename Graph::Edge>
   190 	  ::const_iterator it = _map.find(str.substr(1));
   191 	if (it == _map.end()) {
   192 	  throw DataFormatError("Item not found");
   193 	}
   194 	return _graph.direct(it->second, str[0] == '+');
   195       }
   196     };
   197 
   198     bool isWhiteSpace(char c) {
   199       return c == ' ' || c == '\t' || c == '\v' || 
   200         c == '\n' || c == '\r' || c == '\f'; 
   201     }
   202     
   203     bool isOct(char c) {
   204       return '0' <= c && c <='7'; 
   205     }
   206     
   207     int valueOct(char c) {
   208       LEMON_ASSERT(isOct(c), "The character is not octal.");
   209       return c - '0';
   210     }
   211 
   212     bool isHex(char c) {
   213       return ('0' <= c && c <= '9') || 
   214 	('a' <= c && c <= 'z') || 
   215 	('A' <= c && c <= 'Z'); 
   216     }
   217     
   218     int valueHex(char c) {
   219       LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
   220       if ('0' <= c && c <= '9') return c - '0';
   221       if ('a' <= c && c <= 'z') return c - 'a' + 10;
   222       return c - 'A' + 10;
   223     }
   224 
   225     bool isIdentifierFirstChar(char c) {
   226       return ('a' <= c && c <= 'z') ||
   227 	('A' <= c && c <= 'Z') || c == '_';
   228     }
   229 
   230     bool isIdentifierChar(char c) {
   231       return isIdentifierFirstChar(c) ||
   232 	('0' <= c && c <= '9');
   233     }
   234 
   235     char readEscape(std::istream& is) {
   236       char c;
   237       if (!is.get(c))
   238 	throw DataFormatError("Escape format error");
   239 
   240       switch (c) {
   241       case '\\':
   242 	return '\\';
   243       case '\"':
   244 	return '\"';
   245       case '\'':
   246 	return '\'';
   247       case '\?':
   248 	return '\?';
   249       case 'a':
   250 	return '\a';
   251       case 'b':
   252 	return '\b';
   253       case 'f':
   254 	return '\f';
   255       case 'n':
   256 	return '\n';
   257       case 'r':
   258 	return '\r';
   259       case 't':
   260 	return '\t';
   261       case 'v':
   262 	return '\v';
   263       case 'x':
   264 	{
   265 	  int code;
   266 	  if (!is.get(c) || !isHex(c)) 
   267 	    throw DataFormatError("Escape format error");
   268 	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
   269 	  else code = code * 16 + valueHex(c);
   270 	  return code;
   271 	}
   272       default:
   273 	{
   274 	  int code;
   275 	  if (!isOct(c)) 
   276 	    throw DataFormatError("Escape format error");
   277 	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
   278 	    is.putback(c);
   279 	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
   280 	    is.putback(c);
   281 	  else code = code * 8 + valueOct(c);
   282 	  return code;
   283 	}	      
   284       } 
   285     }
   286     
   287     std::istream& readToken(std::istream& is, std::string& str) {
   288       std::ostringstream os;
   289 
   290       char c;
   291       is >> std::ws;
   292       
   293       if (!is.get(c)) 
   294 	return is;
   295 
   296       if (c == '\"') {
   297 	while (is.get(c) && c != '\"') {
   298 	  if (c == '\\') 
   299 	    c = readEscape(is);
   300 	  os << c;
   301 	}
   302 	if (!is) 
   303 	  throw DataFormatError("Quoted format error");
   304       } else {
   305 	is.putback(c);
   306 	while (is.get(c) && !isWhiteSpace(c)) {
   307 	  if (c == '\\') 
   308 	    c = readEscape(is);
   309 	  os << c;
   310 	}
   311 	if (!is) {
   312 	  is.clear();
   313 	} else {
   314 	  is.putback(c);
   315 	}
   316       }
   317       str = os.str();
   318       return is;
   319     }
   320 
   321     class Section {
   322     public:
   323       virtual ~Section() {}
   324       virtual void process(std::istream& is, int& line_num) = 0;
   325     };
   326 
   327     template <typename Functor>
   328     class LineSection : public Section {
   329     private:
   330 
   331       Functor _functor;
   332 
   333     public:
   334       
   335       LineSection(const Functor& functor) : _functor(functor) {}
   336       virtual ~LineSection() {}
   337 
   338       virtual void process(std::istream& is, int& line_num) {
   339 	char c;
   340 	std::string line;
   341 	while (is.get(c) && c != '@') {
   342 	  if (c == '\n') {
   343 	    ++line_num;
   344 	  } else if (c == '#') {
   345 	    getline(is, line);
   346 	    ++line_num;
   347 	  } else if (!isWhiteSpace(c)) {
   348 	    is.putback(c);
   349 	    getline(is, line);
   350 	    _functor(line);
   351 	    ++line_num;
   352 	  }
   353 	}
   354 	if (is) is.putback(c);
   355 	else if (is.eof()) is.clear();
   356       }
   357     };
   358 
   359     template <typename Functor>
   360     class StreamSection : public Section {
   361     private:
   362 
   363       Functor _functor;
   364 
   365     public:
   366       
   367       StreamSection(const Functor& functor) : _functor(functor) {}
   368       virtual ~StreamSection() {} 
   369 
   370       virtual void process(std::istream& is, int& line_num) {
   371 	_functor(is, line_num);
   372 	char c;
   373 	std::string line;
   374 	while (is.get(c) && c != '@') {
   375 	  if (c == '\n') {
   376 	    ++line_num;
   377 	  } else if (!isWhiteSpace(c)) {
   378 	    getline(is, line);
   379 	    ++line_num;
   380 	  }
   381 	}
   382 	if (is) is.putback(c);
   383 	else if (is.eof()) is.clear();	
   384       }
   385     };
   386     
   387   }
   388 
   389   /// \ingroup lemon_io
   390   ///  
   391   /// \brief LGF reader for directed graphs
   392   ///
   393   /// This utility reads an \ref lgf-format "LGF" file.
   394   ///
   395   /// The reading method does a batch processing. The user creates a
   396   /// reader object, then various reading rules can be added to the
   397   /// reader, and eventually the reading is executed with the \c run()
   398   /// member function. A map reading rule can be added to the reader
   399   /// with the \c nodeMap() or \c arcMap() members. An optional
   400   /// converter parameter can also be added as a standard functor
   401   /// converting from std::string to the value type of the map. If it
   402   /// is set, it will determine how the tokens in the file should be
   403   /// is converted to the map's value type. If the functor is not set,
   404   /// then a default conversion will be used. One map can be read into
   405   /// multiple map objects at the same time. The \c attribute(), \c
   406   /// node() and \c arc() functions are used to add attribute reading
   407   /// rules.
   408   ///
   409   ///\code
   410   ///     DigraphReader<Digraph>(std::cin, digraph).
   411   ///       nodeMap("coordinates", coord_map).
   412   ///       arcMap("capacity", cap_map).
   413   ///       node("source", src).
   414   ///       node("target", trg).
   415   ///       attribute("caption", caption).
   416   ///       run();
   417   ///\endcode
   418   ///
   419   /// By default the reader uses the first section in the file of the
   420   /// proper type. If a section has an optional name, then it can be
   421   /// selected for reading by giving an optional name parameter to the
   422   /// \c nodes(), \c arcs() or \c attributes() functions. The readers
   423   /// also can load extra sections with the \c sectionLines() and
   424   /// sectionStream() functions.
   425   ///
   426   /// The \c useNodes() and \c useArcs() functions are used to tell the reader
   427   /// that the nodes or arcs should not be constructed (added to the
   428   /// graph) during the reading, but instead the label map of the items
   429   /// are given as a parameter of these functions. An
   430   /// application of these function is multipass reading, which is
   431   /// important if two \e \@arcs sections must be read from the
   432   /// file. In this example the first phase would read the node set and one
   433   /// of the arc sets, while the second phase would read the second arc
   434   /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
   435   /// The previously read label node map should be passed to the \c
   436   /// useNodes() functions. Another application of multipass reading when
   437   /// paths are given as a node map or an arc map. It is impossible read this in
   438   /// a single pass, because the arcs are not constructed when the node
   439   /// maps are read.
   440   template <typename _Digraph>
   441   class DigraphReader {
   442   public:
   443 
   444     typedef _Digraph Digraph;
   445     TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
   446     
   447   private:
   448 
   449 
   450     std::istream* _is;
   451     bool local_is;
   452 
   453     Digraph& _digraph;
   454 
   455     std::string _nodes_caption;
   456     std::string _arcs_caption;
   457     std::string _attributes_caption;
   458 
   459     typedef std::map<std::string, Node> NodeIndex;
   460     NodeIndex _node_index;
   461     typedef std::map<std::string, Arc> ArcIndex;
   462     ArcIndex _arc_index;
   463     
   464     typedef std::vector<std::pair<std::string, 
   465       _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
   466     NodeMaps _node_maps; 
   467 
   468     typedef std::vector<std::pair<std::string,
   469       _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
   470     ArcMaps _arc_maps;
   471 
   472     typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
   473       Attributes;
   474     Attributes _attributes;
   475 
   476     typedef std::map<std::string, _reader_bits::Section*> Sections;
   477     Sections _sections;
   478 
   479     bool _use_nodes;
   480     bool _use_arcs;
   481 
   482     bool _skip_nodes;
   483     bool _skip_arcs;
   484 
   485     int line_num;
   486     std::istringstream line;
   487 
   488   public:
   489 
   490     /// \brief Constructor
   491     ///
   492     /// Construct a directed graph reader, which reads from the given
   493     /// input stream.
   494     DigraphReader(std::istream& is, Digraph& digraph) 
   495       : _is(&is), local_is(false), _digraph(digraph),
   496 	_use_nodes(false), _use_arcs(false),
   497 	_skip_nodes(false), _skip_arcs(false) {}
   498 
   499     /// \brief Constructor
   500     ///
   501     /// Construct a directed graph reader, which reads from the given
   502     /// file.
   503     DigraphReader(const std::string& fn, Digraph& digraph) 
   504       : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
   505     	_use_nodes(false), _use_arcs(false),
   506 	_skip_nodes(false), _skip_arcs(false) {}
   507     
   508     /// \brief Constructor
   509     ///
   510     /// Construct a directed graph reader, which reads from the given
   511     /// file.
   512     DigraphReader(const char* fn, Digraph& digraph) 
   513       : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
   514     	_use_nodes(false), _use_arcs(false),
   515 	_skip_nodes(false), _skip_arcs(false) {}
   516 
   517     /// \brief Copy constructor
   518     ///
   519     /// The copy constructor transfers all data from the other reader,
   520     /// therefore the copied reader will not be usable more. 
   521     DigraphReader(DigraphReader& other) 
   522       : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
   523 	_use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
   524 	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
   525 
   526       other._is = 0;
   527       other.local_is = false;
   528       
   529       _node_index.swap(other._node_index);
   530       _arc_index.swap(other._arc_index);
   531 
   532       _node_maps.swap(other._node_maps);
   533       _arc_maps.swap(other._arc_maps);
   534       _attributes.swap(other._attributes);
   535 
   536       _nodes_caption = other._nodes_caption;
   537       _arcs_caption = other._arcs_caption;
   538       _attributes_caption = other._attributes_caption;
   539 
   540       _sections.swap(other._sections);
   541     }
   542 
   543     /// \brief Destructor
   544     ~DigraphReader() {
   545       for (typename NodeMaps::iterator it = _node_maps.begin(); 
   546 	   it != _node_maps.end(); ++it) {
   547 	delete it->second;
   548       }
   549 
   550       for (typename ArcMaps::iterator it = _arc_maps.begin(); 
   551 	   it != _arc_maps.end(); ++it) {
   552 	delete it->second;
   553       }
   554 
   555       for (typename Attributes::iterator it = _attributes.begin(); 
   556 	   it != _attributes.end(); ++it) {
   557 	delete it->second;
   558       }
   559 
   560       for (typename Sections::iterator it = _sections.begin(); 
   561 	   it != _sections.end(); ++it) {
   562 	delete it->second;
   563       }
   564 
   565       if (local_is) {
   566 	delete _is;
   567       }
   568 
   569     }
   570 
   571   private:
   572     
   573     DigraphReader& operator=(const DigraphReader&);
   574 
   575   public:
   576 
   577     /// \name Reading rules
   578     /// @{
   579     
   580     /// \brief Node map reading rule
   581     ///
   582     /// Add a node map reading rule to the reader.
   583     template <typename Map>
   584     DigraphReader& nodeMap(const std::string& caption, Map& map) {
   585       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
   586       _reader_bits::MapStorageBase<Node>* storage = 
   587 	new _reader_bits::MapStorage<Node, Map>(map);
   588       _node_maps.push_back(std::make_pair(caption, storage));
   589       return *this;
   590     }
   591 
   592     /// \brief Node map reading rule
   593     ///
   594     /// Add a node map reading rule with specialized converter to the
   595     /// reader.
   596     template <typename Map, typename Converter>
   597     DigraphReader& nodeMap(const std::string& caption, Map& map, 
   598 			   const Converter& converter = Converter()) {
   599       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
   600       _reader_bits::MapStorageBase<Node>* storage = 
   601 	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
   602       _node_maps.push_back(std::make_pair(caption, storage));
   603       return *this;
   604     }
   605 
   606     /// \brief Arc map reading rule
   607     ///
   608     /// Add an arc map reading rule to the reader.
   609     template <typename Map>
   610     DigraphReader& arcMap(const std::string& caption, Map& map) {
   611       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
   612       _reader_bits::MapStorageBase<Arc>* storage = 
   613 	new _reader_bits::MapStorage<Arc, Map>(map);
   614       _arc_maps.push_back(std::make_pair(caption, storage));
   615       return *this;
   616     }
   617 
   618     /// \brief Arc map reading rule
   619     ///
   620     /// Add an arc map reading rule with specialized converter to the
   621     /// reader.
   622     template <typename Map, typename Converter>
   623     DigraphReader& arcMap(const std::string& caption, Map& map, 
   624 			  const Converter& converter = Converter()) {
   625       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
   626       _reader_bits::MapStorageBase<Arc>* storage = 
   627 	new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
   628       _arc_maps.push_back(std::make_pair(caption, storage));
   629       return *this;
   630     }
   631 
   632     /// \brief Attribute reading rule
   633     ///
   634     /// Add an attribute reading rule to the reader.
   635     template <typename Value>
   636     DigraphReader& attribute(const std::string& caption, Value& value) {
   637       _reader_bits::ValueStorageBase* storage = 
   638 	new _reader_bits::ValueStorage<Value>(value);
   639       _attributes.insert(std::make_pair(caption, storage));
   640       return *this;
   641     }
   642 
   643     /// \brief Attribute reading rule
   644     ///
   645     /// Add an attribute reading rule with specialized converter to the
   646     /// reader.
   647     template <typename Value, typename Converter>
   648     DigraphReader& attribute(const std::string& caption, Value& value, 
   649 			     const Converter& converter = Converter()) {
   650       _reader_bits::ValueStorageBase* storage = 
   651 	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
   652       _attributes.insert(std::make_pair(caption, storage));
   653       return *this;
   654     }
   655 
   656     /// \brief Node reading rule
   657     ///
   658     /// Add a node reading rule to reader.
   659     DigraphReader& node(const std::string& caption, Node& node) {
   660       typedef _reader_bits::MapLookUpConverter<Node> Converter;
   661       Converter converter(_node_index);
   662       _reader_bits::ValueStorageBase* storage = 
   663 	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
   664       _attributes.insert(std::make_pair(caption, storage));
   665       return *this;
   666     }
   667 
   668     /// \brief Arc reading rule
   669     ///
   670     /// Add an arc reading rule to reader.
   671     DigraphReader& arc(const std::string& caption, Arc& arc) {
   672       typedef _reader_bits::MapLookUpConverter<Arc> Converter;
   673       Converter converter(_arc_index);
   674       _reader_bits::ValueStorageBase* storage = 
   675 	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
   676       _attributes.insert(std::make_pair(caption, storage));
   677       return *this;
   678     }
   679 
   680     /// @}
   681 
   682     /// \name Select section by name
   683     /// @{
   684 
   685     /// \brief Set \c \@nodes section to be read
   686     ///
   687     /// Set \c \@nodes section to be read
   688     DigraphReader& nodes(const std::string& caption) {
   689       _nodes_caption = caption;
   690       return *this;
   691     }
   692 
   693     /// \brief Set \c \@arcs section to be read
   694     ///
   695     /// Set \c \@arcs section to be read
   696     DigraphReader& arcs(const std::string& caption) {
   697       _arcs_caption = caption;
   698       return *this;
   699     }
   700 
   701     /// \brief Set \c \@attributes section to be read
   702     ///
   703     /// Set \c \@attributes section to be read
   704     DigraphReader& attributes(const std::string& caption) {
   705       _attributes_caption = caption;
   706       return *this;
   707     }
   708 
   709     /// @}
   710 
   711     /// \name Section readers
   712     /// @{
   713 
   714     /// \brief Add a section processor with line oriented reading
   715     ///
   716     /// In the \e LGF file extra sections can be placed, which contain
   717     /// any data in arbitrary format. These sections can be read with
   718     /// this function line by line. The first parameter is the type
   719     /// descriptor of the section, the second is a functor, which
   720     /// takes just one \c std::string parameter. At the reading
   721     /// process, each line of the section will be given to the functor
   722     /// object. However, the empty lines and the comment lines are
   723     /// filtered out, and the leading whitespaces are stipped from
   724     /// each processed string.
   725     ///
   726     /// For example let's see a section, which contain several
   727     /// integers, which should be inserted into a vector.
   728     ///\code
   729     ///  @numbers
   730     ///  12 45 23
   731     ///  4
   732     ///  23 6
   733     ///\endcode
   734     ///
   735     /// The functor is implemented as an struct:
   736     ///\code
   737     ///  struct NumberSection {
   738     ///    std::vector<int>& _data;
   739     ///    NumberSection(std::vector<int>& data) : _data(data) {}
   740     ///    void operator()(const std::string& line) {
   741     ///      std::istringstream ls(line);
   742     ///      int value;
   743     ///      while (ls >> value) _data.push_back(value);
   744     ///    }
   745     ///  };
   746     ///
   747     ///  // ...
   748     ///
   749     ///  reader.sectionLines("numbers", NumberSection(vec));  
   750     ///\endcode
   751     template <typename Functor>
   752     DigraphReader& sectionLines(const std::string& type, Functor functor) {
   753       LEMON_ASSERT(!type.empty(), "Type is not empty.");
   754       LEMON_ASSERT(_sections.find(type) == _sections.end(), 
   755 		   "Multiple reading of section.");
   756       LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
   757 		   type != "attributes", "Multiple reading of section.");
   758       _sections.insert(std::make_pair(type, 
   759         new _reader_bits::LineSection<Functor>(functor)));
   760       return *this;
   761     }
   762 
   763 
   764     /// \brief Add a section processor with stream oriented reading
   765     ///
   766     /// In the \e LGF file extra sections can be placed, which contain
   767     /// any data in arbitrary format. These sections can be read
   768     /// directly with this function. The first parameter is the type
   769     /// of the section, the second is a functor, which takes an \c
   770     /// std::istream& and an int& parameter, the latter regard to the
   771     /// line number of stream. The functor can read the input while
   772     /// the section go on, and the line number should be modified
   773     /// accordingly.
   774     template <typename Functor>
   775     DigraphReader& sectionStream(const std::string& type, Functor functor) {
   776       LEMON_ASSERT(!type.empty(), "Type is not empty.");
   777       LEMON_ASSERT(_sections.find(type) == _sections.end(), 
   778 		   "Multiple reading of section.");
   779       LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
   780 		   type != "attributes", "Multiple reading of section.");
   781       _sections.insert(std::make_pair(type, 
   782 	 new _reader_bits::StreamSection<Functor>(functor)));
   783       return *this;
   784     }    
   785     
   786     /// @}
   787 
   788     /// \name Using previously constructed node or arc set
   789     /// @{
   790 
   791     /// \brief Use previously constructed node set
   792     ///
   793     /// Use previously constructed node set, and specify the node
   794     /// label map.
   795     template <typename Map>
   796     DigraphReader& useNodes(const Map& map) {
   797       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   798       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
   799       _use_nodes = true;
   800       _writer_bits::DefaultConverter<typename Map::Value> converter;
   801       for (NodeIt n(_digraph); n != INVALID; ++n) {
   802 	_node_index.insert(std::make_pair(converter(map[n]), n));
   803       }
   804       return *this;
   805     }
   806 
   807     /// \brief Use previously constructed node set
   808     ///
   809     /// Use previously constructed node set, and specify the node
   810     /// label map and a functor which converts the label map values to
   811     /// std::string.
   812     template <typename Map, typename Converter>
   813     DigraphReader& useNodes(const Map& map, 
   814 			    const Converter& converter = Converter()) {
   815       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   816       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
   817       _use_nodes = true;
   818       for (NodeIt n(_digraph); n != INVALID; ++n) {
   819 	_node_index.insert(std::make_pair(converter(map[n]), n));
   820       }
   821       return *this;
   822     }
   823 
   824     /// \brief Use previously constructed arc set
   825     ///
   826     /// Use previously constructed arc set, and specify the arc
   827     /// label map.
   828     template <typename Map>
   829     DigraphReader& useArcs(const Map& map) {
   830       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   831       LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
   832       _use_arcs = true;
   833       _writer_bits::DefaultConverter<typename Map::Value> converter;
   834       for (ArcIt a(_digraph); a != INVALID; ++a) {
   835 	_arc_index.insert(std::make_pair(converter(map[a]), a));
   836       }
   837       return *this;
   838     }
   839 
   840     /// \brief Use previously constructed arc set
   841     ///
   842     /// Use previously constructed arc set, and specify the arc
   843     /// label map and a functor which converts the label map values to
   844     /// std::string.
   845     template <typename Map, typename Converter>
   846     DigraphReader& useArcs(const Map& map, 
   847 			   const Converter& converter = Converter()) {
   848       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   849       LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); 
   850       _use_arcs = true;
   851       for (ArcIt a(_digraph); a != INVALID; ++a) {
   852 	_arc_index.insert(std::make_pair(converter(map[a]), a));
   853       }
   854       return *this;
   855     }
   856 
   857     /// \brief Skips the reading of node section
   858     ///
   859     /// Omit the reading of the node section. This implies that each node
   860     /// map reading rule will be abanoned, and the nodes of the graph
   861     /// will not be constructed, which usually cause that the arc set
   862     /// could not be read due to lack of node name
   863     /// resolving. Therefore, the \c skipArcs() should be used too, or
   864     /// the useNodes() member function should be used to specify the
   865     /// label of the nodes.
   866     DigraphReader& skipNodes() {
   867       LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 
   868       _skip_nodes = true;
   869       return *this;
   870     }
   871 
   872     /// \brief Skips the reading of arc section
   873     ///
   874     /// Omit the reading of the arc section. This implies that each arc
   875     /// map reading rule will be abanoned, and the arcs of the graph
   876     /// will not be constructed.
   877     DigraphReader& skipArcs() {
   878       LEMON_ASSERT(!_skip_arcs, "Skip arcs already set"); 
   879       _skip_arcs = true;
   880       return *this;
   881     }
   882 
   883     /// @}
   884 
   885   private:
   886 
   887     bool readLine() {
   888       std::string str;
   889       while(++line_num, std::getline(*_is, str)) {
   890 	line.clear(); line.str(str);
   891 	char c;
   892 	if (line >> std::ws >> c && c != '#') {
   893 	  line.putback(c);
   894 	  return true;
   895 	}
   896       }
   897       return false;
   898     }
   899 
   900     bool readSuccess() {
   901       return static_cast<bool>(*_is);
   902     }
   903     
   904     void skipSection() {
   905       char c;
   906       while (readSuccess() && line >> c && c != '@') {
   907 	readLine();
   908       }
   909       line.putback(c);
   910     }
   911 
   912     void readNodes() {
   913 
   914       std::vector<int> map_index(_node_maps.size());
   915       int map_num, label_index;
   916 
   917       char c;
   918       if (!readLine() || !(line >> c) || c == '@') {
   919 	if (readSuccess() && line) line.putback(c);
   920 	if (!_node_maps.empty()) 
   921 	  throw DataFormatError("Cannot find map names");
   922 	return;
   923       }
   924       line.putback(c);
   925 
   926       {
   927 	std::map<std::string, int> maps;
   928 	
   929 	std::string map;
   930 	int index = 0;
   931 	while (_reader_bits::readToken(line, map)) {
   932 	  if (maps.find(map) != maps.end()) {
   933 	    std::ostringstream msg;
   934 	    msg << "Multiple occurence of node map: " << map;
   935 	    throw DataFormatError(msg.str().c_str());
   936 	  }
   937 	  maps.insert(std::make_pair(map, index));
   938 	  ++index;
   939 	}
   940 	
   941 	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
   942 	  std::map<std::string, int>::iterator jt = 
   943 	    maps.find(_node_maps[i].first);
   944 	  if (jt == maps.end()) {
   945 	    std::ostringstream msg;
   946 	    msg << "Map not found in file: " << _node_maps[i].first;
   947 	    throw DataFormatError(msg.str().c_str());
   948 	  }
   949 	  map_index[i] = jt->second;
   950 	}
   951 
   952 	{
   953 	  std::map<std::string, int>::iterator jt = maps.find("label");
   954 	  if (jt != maps.end()) {
   955 	    label_index = jt->second;
   956 	  } else {
   957 	    label_index = -1;
   958 	  }
   959 	}
   960 	map_num = maps.size();
   961       }
   962 
   963       while (readLine() && line >> c && c != '@') {
   964 	line.putback(c);
   965 
   966 	std::vector<std::string> tokens(map_num);
   967 	for (int i = 0; i < map_num; ++i) {
   968 	  if (!_reader_bits::readToken(line, tokens[i])) {
   969 	    std::ostringstream msg;
   970 	    msg << "Column not found (" << i + 1 << ")";
   971 	    throw DataFormatError(msg.str().c_str());
   972 	  }
   973 	}
   974 	if (line >> std::ws >> c)
   975 	  throw DataFormatError("Extra character on the end of line");
   976 	
   977 	Node n;
   978 	if (!_use_nodes) {
   979 	  n = _digraph.addNode();
   980 	  if (label_index != -1)
   981 	    _node_index.insert(std::make_pair(tokens[label_index], n));
   982 	} else {
   983 	  if (label_index == -1) 
   984 	    throw DataFormatError("Label map not found in file");
   985 	  typename std::map<std::string, Node>::iterator it =
   986 	    _node_index.find(tokens[label_index]);
   987 	  if (it == _node_index.end()) {
   988 	    std::ostringstream msg;
   989 	    msg << "Node with label not found: " << tokens[label_index];
   990 	    throw DataFormatError(msg.str().c_str());	    
   991 	  }
   992 	  n = it->second;
   993 	}
   994 
   995 	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
   996 	  _node_maps[i].second->set(n, tokens[map_index[i]]);
   997 	}
   998 
   999       }
  1000       if (readSuccess()) {
  1001 	line.putback(c);
  1002       }
  1003     }
  1004 
  1005     void readArcs() {
  1006 
  1007       std::vector<int> map_index(_arc_maps.size());
  1008       int map_num, label_index;
  1009 
  1010       char c;
  1011       if (!readLine() || !(line >> c) || c == '@') {
  1012 	if (readSuccess() && line) line.putback(c);
  1013 	if (!_arc_maps.empty()) 
  1014 	  throw DataFormatError("Cannot find map names");
  1015 	return;
  1016       }
  1017       line.putback(c);
  1018       
  1019       {
  1020 	std::map<std::string, int> maps;
  1021 	
  1022 	std::string map;
  1023 	int index = 0;
  1024 	while (_reader_bits::readToken(line, map)) {
  1025 	  if (maps.find(map) != maps.end()) {
  1026 	    std::ostringstream msg;
  1027 	    msg << "Multiple occurence of arc map: " << map;
  1028 	    throw DataFormatError(msg.str().c_str());
  1029 	  }
  1030 	  maps.insert(std::make_pair(map, index));
  1031 	  ++index;
  1032 	}
  1033 	
  1034 	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
  1035 	  std::map<std::string, int>::iterator jt = 
  1036 	    maps.find(_arc_maps[i].first);
  1037 	  if (jt == maps.end()) {
  1038 	    std::ostringstream msg;
  1039 	    msg << "Map not found in file: " << _arc_maps[i].first;
  1040 	    throw DataFormatError(msg.str().c_str());
  1041 	  }
  1042 	  map_index[i] = jt->second;
  1043 	}
  1044 
  1045 	{
  1046 	  std::map<std::string, int>::iterator jt = maps.find("label");
  1047 	  if (jt != maps.end()) {
  1048 	    label_index = jt->second;
  1049 	  } else {
  1050 	    label_index = -1;
  1051 	  }
  1052 	}
  1053 	map_num = maps.size();
  1054       }
  1055 
  1056       while (readLine() && line >> c && c != '@') {
  1057 	line.putback(c);
  1058 
  1059 	std::string source_token;
  1060 	std::string target_token;
  1061 
  1062 	if (!_reader_bits::readToken(line, source_token))
  1063 	  throw DataFormatError("Source not found");
  1064 
  1065 	if (!_reader_bits::readToken(line, target_token))
  1066 	  throw DataFormatError("Target not found");
  1067 	
  1068 	std::vector<std::string> tokens(map_num);
  1069 	for (int i = 0; i < map_num; ++i) {
  1070 	  if (!_reader_bits::readToken(line, tokens[i])) {
  1071 	    std::ostringstream msg;
  1072 	    msg << "Column not found (" << i + 1 << ")";
  1073 	    throw DataFormatError(msg.str().c_str());
  1074 	  }
  1075 	}
  1076 	if (line >> std::ws >> c)
  1077 	  throw DataFormatError("Extra character on the end of line");
  1078 	
  1079 	Arc a;
  1080 	if (!_use_arcs) {
  1081 
  1082           typename NodeIndex::iterator it;
  1083  
  1084           it = _node_index.find(source_token);
  1085           if (it == _node_index.end()) {
  1086             std::ostringstream msg;
  1087             msg << "Item not found: " << source_token;
  1088             throw DataFormatError(msg.str().c_str());
  1089           }
  1090           Node source = it->second;
  1091 
  1092           it = _node_index.find(target_token);
  1093           if (it == _node_index.end()) {       
  1094             std::ostringstream msg;            
  1095             msg << "Item not found: " << target_token;
  1096             throw DataFormatError(msg.str().c_str());
  1097           }                                          
  1098           Node target = it->second;                            
  1099 
  1100 	  a = _digraph.addArc(source, target);
  1101 	  if (label_index != -1) 
  1102 	    _arc_index.insert(std::make_pair(tokens[label_index], a));
  1103 	} else {
  1104 	  if (label_index == -1) 
  1105 	    throw DataFormatError("Label map not found in file");
  1106 	  typename std::map<std::string, Arc>::iterator it =
  1107 	    _arc_index.find(tokens[label_index]);
  1108 	  if (it == _arc_index.end()) {
  1109 	    std::ostringstream msg;
  1110 	    msg << "Arc with label not found: " << tokens[label_index];
  1111 	    throw DataFormatError(msg.str().c_str());	    
  1112 	  }
  1113 	  a = it->second;
  1114 	}
  1115 
  1116 	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
  1117 	  _arc_maps[i].second->set(a, tokens[map_index[i]]);
  1118 	}
  1119 
  1120       }
  1121       if (readSuccess()) {
  1122 	line.putback(c);
  1123       }
  1124     }
  1125 
  1126     void readAttributes() {
  1127 
  1128       std::set<std::string> read_attr;
  1129 
  1130       char c;
  1131       while (readLine() && line >> c && c != '@') {
  1132 	line.putback(c);
  1133 	
  1134 	std::string attr, token;
  1135 	if (!_reader_bits::readToken(line, attr))
  1136 	  throw DataFormatError("Attribute name not found");
  1137 	if (!_reader_bits::readToken(line, token))
  1138 	  throw DataFormatError("Attribute value not found");
  1139 	if (line >> c)
  1140 	  throw DataFormatError("Extra character on the end of line");	  
  1141 
  1142 	{
  1143 	  std::set<std::string>::iterator it = read_attr.find(attr);
  1144 	  if (it != read_attr.end()) {
  1145 	    std::ostringstream msg;
  1146 	    msg << "Multiple occurence of attribute " << attr;
  1147 	    throw DataFormatError(msg.str().c_str());
  1148 	  }
  1149 	  read_attr.insert(attr);
  1150 	}
  1151 	
  1152 	{
  1153 	  typename Attributes::iterator it = _attributes.lower_bound(attr);
  1154 	  while (it != _attributes.end() && it->first == attr) {
  1155 	    it->second->set(token);
  1156 	    ++it;
  1157 	  }
  1158 	}
  1159 
  1160       }
  1161       if (readSuccess()) {
  1162 	line.putback(c);
  1163       }
  1164       for (typename Attributes::iterator it = _attributes.begin();
  1165 	   it != _attributes.end(); ++it) {
  1166 	if (read_attr.find(it->first) == read_attr.end()) {
  1167 	  std::ostringstream msg;
  1168 	  msg << "Attribute not found in file: " << it->first;
  1169 	  throw DataFormatError(msg.str().c_str());
  1170 	}	
  1171       }
  1172     }
  1173 
  1174   public:
  1175 
  1176     /// \name Execution of the reader    
  1177     /// @{
  1178 
  1179     /// \brief Start the batch processing
  1180     ///
  1181     /// This function starts the batch processing
  1182     void run() {
  1183       LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
  1184       if (!*_is) {
  1185 	throw DataFormatError("Cannot find file");
  1186       }
  1187       
  1188       bool nodes_done = _skip_nodes;
  1189       bool arcs_done = _skip_arcs;
  1190       bool attributes_done = false;
  1191       std::set<std::string> extra_sections;
  1192 
  1193       line_num = 0;      
  1194       readLine();
  1195       skipSection();
  1196 
  1197       while (readSuccess()) {
  1198 	try {
  1199 	  char c;
  1200 	  std::string section, caption;
  1201 	  line >> c;
  1202 	  _reader_bits::readToken(line, section);
  1203 	  _reader_bits::readToken(line, caption);
  1204 
  1205 	  if (line >> c) 
  1206 	    throw DataFormatError("Extra character on the end of line");
  1207 
  1208 	  if (section == "nodes" && !nodes_done) {
  1209 	    if (_nodes_caption.empty() || _nodes_caption == caption) {
  1210 	      readNodes();
  1211 	      nodes_done = true;
  1212 	    }
  1213 	  } else if ((section == "arcs" || section == "edges") && 
  1214 		     !arcs_done) {
  1215 	    if (_arcs_caption.empty() || _arcs_caption == caption) {
  1216 	      readArcs();
  1217 	      arcs_done = true;
  1218 	    }
  1219 	  } else if (section == "attributes" && !attributes_done) {
  1220 	    if (_attributes_caption.empty() || _attributes_caption == caption) {
  1221 	      readAttributes();
  1222 	      attributes_done = true;
  1223 	    }
  1224 	  } else {
  1225 	    if (extra_sections.find(section) != extra_sections.end()) {
  1226 	      std::ostringstream msg;
  1227 	      msg << "Multiple occurence of section " << section;
  1228 	      throw DataFormatError(msg.str().c_str());
  1229 	    }
  1230 	    Sections::iterator it = _sections.find(section);
  1231 	    if (it != _sections.end()) {
  1232 	      extra_sections.insert(section);
  1233 	      it->second->process(*_is, line_num);
  1234 	    }
  1235 	    readLine();
  1236 	    skipSection();
  1237 	  }
  1238 	} catch (DataFormatError& error) {
  1239 	  error.line(line_num);
  1240 	  throw;
  1241 	}	
  1242       }
  1243 
  1244       if (!nodes_done) {
  1245 	throw DataFormatError("Section @nodes not found");
  1246       }
  1247 
  1248       if (!arcs_done) {
  1249 	throw DataFormatError("Section @arcs not found");
  1250       }
  1251 
  1252       if (!attributes_done && !_attributes.empty()) {
  1253 	throw DataFormatError("Section @attributes not found");
  1254       }
  1255 
  1256     }
  1257 
  1258     /// @}
  1259     
  1260   };
  1261 
  1262   /// \relates DigraphReader
  1263   template <typename Digraph>
  1264   DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
  1265     DigraphReader<Digraph> tmp(is, digraph);
  1266     return tmp;
  1267   }
  1268 
  1269   /// \relates DigraphReader
  1270   template <typename Digraph>
  1271   DigraphReader<Digraph> digraphReader(const std::string& fn, 
  1272 				       Digraph& digraph) {
  1273     DigraphReader<Digraph> tmp(fn, digraph);
  1274     return tmp;
  1275   }
  1276 
  1277   /// \relates DigraphReader
  1278   template <typename Digraph>
  1279   DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
  1280     DigraphReader<Digraph> tmp(fn, digraph);
  1281     return tmp;
  1282   }
  1283 
  1284   /// \ingroup lemon_io
  1285   ///  
  1286   /// \brief LGF reader for undirected graphs
  1287   ///
  1288   /// This utility reads an \ref lgf-format "LGF" file.
  1289   template <typename _Graph>
  1290   class GraphReader {
  1291   public:
  1292 
  1293     typedef _Graph Graph;
  1294     TEMPLATE_GRAPH_TYPEDEFS(Graph);
  1295     
  1296   private:
  1297 
  1298 
  1299     std::istream* _is;
  1300     bool local_is;
  1301 
  1302     Graph& _graph;
  1303 
  1304     std::string _nodes_caption;
  1305     std::string _edges_caption;
  1306     std::string _attributes_caption;
  1307 
  1308     typedef std::map<std::string, Node> NodeIndex;
  1309     NodeIndex _node_index;
  1310     typedef std::map<std::string, Edge> EdgeIndex;
  1311     EdgeIndex _edge_index;
  1312     
  1313     typedef std::vector<std::pair<std::string, 
  1314       _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
  1315     NodeMaps _node_maps; 
  1316 
  1317     typedef std::vector<std::pair<std::string,
  1318       _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
  1319     EdgeMaps _edge_maps;
  1320 
  1321     typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
  1322       Attributes;
  1323     Attributes _attributes;
  1324 
  1325     typedef std::map<std::string, _reader_bits::Section*> Sections;
  1326     Sections _sections;
  1327 
  1328     bool _use_nodes;
  1329     bool _use_edges;
  1330 
  1331     bool _skip_nodes;
  1332     bool _skip_edges;
  1333 
  1334     int line_num;
  1335     std::istringstream line;
  1336 
  1337   public:
  1338 
  1339     /// \brief Constructor
  1340     ///
  1341     /// Construct a undirected graph reader, which reads from the given
  1342     /// input stream.
  1343     GraphReader(std::istream& is, Graph& graph) 
  1344       : _is(&is), local_is(false), _graph(graph),
  1345 	_use_nodes(false), _use_edges(false),
  1346 	_skip_nodes(false), _skip_edges(false) {}
  1347 
  1348     /// \brief Constructor
  1349     ///
  1350     /// Construct a undirected graph reader, which reads from the given
  1351     /// file.
  1352     GraphReader(const std::string& fn, Graph& graph) 
  1353       : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph),
  1354     	_use_nodes(false), _use_edges(false),
  1355 	_skip_nodes(false), _skip_edges(false) {}
  1356     
  1357     /// \brief Constructor
  1358     ///
  1359     /// Construct a undirected graph reader, which reads from the given
  1360     /// file.
  1361     GraphReader(const char* fn, Graph& graph) 
  1362       : _is(new std::ifstream(fn)), local_is(true), _graph(graph),
  1363     	_use_nodes(false), _use_edges(false),
  1364 	_skip_nodes(false), _skip_edges(false) {}
  1365 
  1366     /// \brief Copy constructor
  1367     ///
  1368     /// The copy constructor transfers all data from the other reader,
  1369     /// therefore the copied reader will not be usable more. 
  1370     GraphReader(GraphReader& other) 
  1371       : _is(other._is), local_is(other.local_is), _graph(other._graph),
  1372 	_use_nodes(other._use_nodes), _use_edges(other._use_edges),
  1373 	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
  1374 
  1375       other._is = 0;
  1376       other.local_is = false;
  1377       
  1378       _node_index.swap(other._node_index);
  1379       _edge_index.swap(other._edge_index);
  1380 
  1381       _node_maps.swap(other._node_maps);
  1382       _edge_maps.swap(other._edge_maps);
  1383       _attributes.swap(other._attributes);
  1384 
  1385       _nodes_caption = other._nodes_caption;
  1386       _edges_caption = other._edges_caption;
  1387       _attributes_caption = other._attributes_caption;
  1388 
  1389       _sections.swap(other._sections);
  1390     }
  1391 
  1392     /// \brief Destructor
  1393     ~GraphReader() {
  1394       for (typename NodeMaps::iterator it = _node_maps.begin(); 
  1395 	   it != _node_maps.end(); ++it) {
  1396 	delete it->second;
  1397       }
  1398 
  1399       for (typename EdgeMaps::iterator it = _edge_maps.begin(); 
  1400 	   it != _edge_maps.end(); ++it) {
  1401 	delete it->second;
  1402       }
  1403 
  1404       for (typename Attributes::iterator it = _attributes.begin(); 
  1405 	   it != _attributes.end(); ++it) {
  1406 	delete it->second;
  1407       }
  1408 
  1409       for (typename Sections::iterator it = _sections.begin(); 
  1410 	   it != _sections.end(); ++it) {
  1411 	delete it->second;
  1412       }
  1413 
  1414       if (local_is) {
  1415 	delete _is;
  1416       }
  1417 
  1418     }
  1419 
  1420   private:
  1421     
  1422     GraphReader& operator=(const GraphReader&);
  1423 
  1424   public:
  1425 
  1426     /// \name Reading rules
  1427     /// @{
  1428     
  1429     /// \brief Node map reading rule
  1430     ///
  1431     /// Add a node map reading rule to the reader.
  1432     template <typename Map>
  1433     GraphReader& nodeMap(const std::string& caption, Map& map) {
  1434       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
  1435       _reader_bits::MapStorageBase<Node>* storage = 
  1436 	new _reader_bits::MapStorage<Node, Map>(map);
  1437       _node_maps.push_back(std::make_pair(caption, storage));
  1438       return *this;
  1439     }
  1440 
  1441     /// \brief Node map reading rule
  1442     ///
  1443     /// Add a node map reading rule with specialized converter to the
  1444     /// reader.
  1445     template <typename Map, typename Converter>
  1446     GraphReader& nodeMap(const std::string& caption, Map& map, 
  1447 			   const Converter& converter = Converter()) {
  1448       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
  1449       _reader_bits::MapStorageBase<Node>* storage = 
  1450 	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
  1451       _node_maps.push_back(std::make_pair(caption, storage));
  1452       return *this;
  1453     }
  1454 
  1455     /// \brief Edge map reading rule
  1456     ///
  1457     /// Add an edge map reading rule to the reader.
  1458     template <typename Map>
  1459     GraphReader& edgeMap(const std::string& caption, Map& map) {
  1460       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
  1461       _reader_bits::MapStorageBase<Edge>* storage = 
  1462 	new _reader_bits::MapStorage<Edge, Map>(map);
  1463       _edge_maps.push_back(std::make_pair(caption, storage));
  1464       return *this;
  1465     }
  1466 
  1467     /// \brief Edge map reading rule
  1468     ///
  1469     /// Add an edge map reading rule with specialized converter to the
  1470     /// reader.
  1471     template <typename Map, typename Converter>
  1472     GraphReader& edgeMap(const std::string& caption, Map& map, 
  1473 			  const Converter& converter = Converter()) {
  1474       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
  1475       _reader_bits::MapStorageBase<Edge>* storage = 
  1476 	new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
  1477       _edge_maps.push_back(std::make_pair(caption, storage));
  1478       return *this;
  1479     }
  1480 
  1481     /// \brief Arc map reading rule
  1482     ///
  1483     /// Add an arc map reading rule to the reader.
  1484     template <typename Map>
  1485     GraphReader& arcMap(const std::string& caption, Map& map) {
  1486       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
  1487       _reader_bits::MapStorageBase<Edge>* forward_storage = 
  1488 	new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
  1489       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
  1490       _reader_bits::MapStorageBase<Edge>* backward_storage = 
  1491 	new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
  1492       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
  1493       return *this;
  1494     }
  1495 
  1496     /// \brief Arc map reading rule
  1497     ///
  1498     /// Add an arc map reading rule with specialized converter to the
  1499     /// reader.
  1500     template <typename Map, typename Converter>
  1501     GraphReader& arcMap(const std::string& caption, Map& map, 
  1502 			  const Converter& converter = Converter()) {
  1503       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
  1504       _reader_bits::MapStorageBase<Edge>* forward_storage = 
  1505 	new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
  1506 	(_graph, map, converter);
  1507       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
  1508       _reader_bits::MapStorageBase<Edge>* backward_storage = 
  1509 	new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
  1510 	(_graph, map, converter);
  1511       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
  1512       return *this;
  1513     }
  1514 
  1515     /// \brief Attribute reading rule
  1516     ///
  1517     /// Add an attribute reading rule to the reader.
  1518     template <typename Value>
  1519     GraphReader& attribute(const std::string& caption, Value& value) {
  1520       _reader_bits::ValueStorageBase* storage = 
  1521 	new _reader_bits::ValueStorage<Value>(value);
  1522       _attributes.insert(std::make_pair(caption, storage));
  1523       return *this;
  1524     }
  1525 
  1526     /// \brief Attribute reading rule
  1527     ///
  1528     /// Add an attribute reading rule with specialized converter to the
  1529     /// reader.
  1530     template <typename Value, typename Converter>
  1531     GraphReader& attribute(const std::string& caption, Value& value, 
  1532 			     const Converter& converter = Converter()) {
  1533       _reader_bits::ValueStorageBase* storage = 
  1534 	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
  1535       _attributes.insert(std::make_pair(caption, storage));
  1536       return *this;
  1537     }
  1538 
  1539     /// \brief Node reading rule
  1540     ///
  1541     /// Add a node reading rule to reader.
  1542     GraphReader& node(const std::string& caption, Node& node) {
  1543       typedef _reader_bits::MapLookUpConverter<Node> Converter;
  1544       Converter converter(_node_index);
  1545       _reader_bits::ValueStorageBase* storage = 
  1546 	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
  1547       _attributes.insert(std::make_pair(caption, storage));
  1548       return *this;
  1549     }
  1550 
  1551     /// \brief Edge reading rule
  1552     ///
  1553     /// Add an edge reading rule to reader.
  1554     GraphReader& edge(const std::string& caption, Edge& edge) {
  1555       typedef _reader_bits::MapLookUpConverter<Edge> Converter;
  1556       Converter converter(_edge_index);
  1557       _reader_bits::ValueStorageBase* storage = 
  1558 	new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
  1559       _attributes.insert(std::make_pair(caption, storage));
  1560       return *this;
  1561     }
  1562 
  1563     /// \brief Arc reading rule
  1564     ///
  1565     /// Add an arc reading rule to reader.
  1566     GraphReader& arc(const std::string& caption, Arc& arc) {
  1567       typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
  1568       Converter converter(_graph, _edge_index);
  1569       _reader_bits::ValueStorageBase* storage = 
  1570 	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
  1571       _attributes.insert(std::make_pair(caption, storage));
  1572       return *this;
  1573     }
  1574 
  1575     /// @}
  1576 
  1577     /// \name Select section by name
  1578     /// @{
  1579 
  1580     /// \brief Set \c \@nodes section to be read
  1581     ///
  1582     /// Set \c \@nodes section to be read
  1583     GraphReader& nodes(const std::string& caption) {
  1584       _nodes_caption = caption;
  1585       return *this;
  1586     }
  1587 
  1588     /// \brief Set \c \@edges section to be read
  1589     ///
  1590     /// Set \c \@edges section to be read
  1591     GraphReader& edges(const std::string& caption) {
  1592       _edges_caption = caption;
  1593       return *this;
  1594     }
  1595 
  1596     /// \brief Set \c \@attributes section to be read
  1597     ///
  1598     /// Set \c \@attributes section to be read
  1599     GraphReader& attributes(const std::string& caption) {
  1600       _attributes_caption = caption;
  1601       return *this;
  1602     }
  1603 
  1604     /// @}
  1605 
  1606     /// \name Section readers
  1607     /// @{
  1608 
  1609     /// \brief Add a section processor with line oriented reading
  1610     ///
  1611     /// In the \e LGF file extra sections can be placed, which contain
  1612     /// any data in arbitrary format. These sections can be read with
  1613     /// this function line by line. The first parameter is the type
  1614     /// descriptor of the section, the second is a functor, which
  1615     /// takes just one \c std::string parameter. At the reading
  1616     /// process, each line of the section will be given to the functor
  1617     /// object. However, the empty lines and the comment lines are
  1618     /// filtered out, and the leading whitespaces are stipped from
  1619     /// each processed string.
  1620     ///
  1621     /// For example let's see a section, which contain several
  1622     /// integers, which should be inserted into a vector.
  1623     ///\code
  1624     ///  @numbers
  1625     ///  12 45 23
  1626     ///  4
  1627     ///  23 6
  1628     ///\endcode
  1629     ///
  1630     /// The functor is implemented as an struct:
  1631     ///\code
  1632     ///  struct NumberSection {
  1633     ///    std::vector<int>& _data;
  1634     ///    NumberSection(std::vector<int>& data) : _data(data) {}
  1635     ///    void operator()(const std::string& line) {
  1636     ///      std::istringstream ls(line);
  1637     ///      int value;
  1638     ///      while (ls >> value) _data.push_back(value);
  1639     ///    }
  1640     ///  };
  1641     ///
  1642     ///  // ...
  1643     ///
  1644     ///  reader.sectionLines("numbers", NumberSection(vec));  
  1645     ///\endcode
  1646     template <typename Functor>
  1647     GraphReader& sectionLines(const std::string& type, Functor functor) {
  1648       LEMON_ASSERT(!type.empty(), "Type is not empty.");
  1649       LEMON_ASSERT(_sections.find(type) == _sections.end(), 
  1650 		   "Multiple reading of section.");
  1651       LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
  1652 		   type != "attributes", "Multiple reading of section.");
  1653       _sections.insert(std::make_pair(type, 
  1654         new _reader_bits::LineSection<Functor>(functor)));
  1655       return *this;
  1656     }
  1657 
  1658 
  1659     /// \brief Add a section processor with stream oriented reading
  1660     ///
  1661     /// In the \e LGF file extra sections can be placed, which contain
  1662     /// any data in arbitrary format. These sections can be read
  1663     /// directly with this function. The first parameter is the type
  1664     /// of the section, the second is a functor, which takes an \c
  1665     /// std::istream& and an int& parameter, the latter regard to the
  1666     /// line number of stream. The functor can read the input while
  1667     /// the section go on, and the line number should be modified
  1668     /// accordingly.
  1669     template <typename Functor>
  1670     GraphReader& sectionStream(const std::string& type, Functor functor) {
  1671       LEMON_ASSERT(!type.empty(), "Type is not empty.");
  1672       LEMON_ASSERT(_sections.find(type) == _sections.end(), 
  1673 		   "Multiple reading of section.");
  1674       LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
  1675 		   type != "attributes", "Multiple reading of section.");
  1676       _sections.insert(std::make_pair(type, 
  1677 	 new _reader_bits::StreamSection<Functor>(functor)));
  1678       return *this;
  1679     }    
  1680     
  1681     /// @}
  1682 
  1683     /// \name Using previously constructed node or edge set
  1684     /// @{
  1685 
  1686     /// \brief Use previously constructed node set
  1687     ///
  1688     /// Use previously constructed node set, and specify the node
  1689     /// label map.
  1690     template <typename Map>
  1691     GraphReader& useNodes(const Map& map) {
  1692       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
  1693       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
  1694       _use_nodes = true;
  1695       _writer_bits::DefaultConverter<typename Map::Value> converter;
  1696       for (NodeIt n(_graph); n != INVALID; ++n) {
  1697 	_node_index.insert(std::make_pair(converter(map[n]), n));
  1698       }
  1699       return *this;
  1700     }
  1701 
  1702     /// \brief Use previously constructed node set
  1703     ///
  1704     /// Use previously constructed node set, and specify the node
  1705     /// label map and a functor which converts the label map values to
  1706     /// std::string.
  1707     template <typename Map, typename Converter>
  1708     GraphReader& useNodes(const Map& map, 
  1709 			    const Converter& converter = Converter()) {
  1710       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
  1711       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
  1712       _use_nodes = true;
  1713       for (NodeIt n(_graph); n != INVALID; ++n) {
  1714 	_node_index.insert(std::make_pair(converter(map[n]), n));
  1715       }
  1716       return *this;
  1717     }
  1718 
  1719     /// \brief Use previously constructed edge set
  1720     ///
  1721     /// Use previously constructed edge set, and specify the edge
  1722     /// label map.
  1723     template <typename Map>
  1724     GraphReader& useEdges(const Map& map) {
  1725       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
  1726       LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
  1727       _use_edges = true;
  1728       _writer_bits::DefaultConverter<typename Map::Value> converter;
  1729       for (EdgeIt a(_graph); a != INVALID; ++a) {
  1730 	_edge_index.insert(std::make_pair(converter(map[a]), a));
  1731       }
  1732       return *this;
  1733     }
  1734 
  1735     /// \brief Use previously constructed edge set
  1736     ///
  1737     /// Use previously constructed edge set, and specify the edge
  1738     /// label map and a functor which converts the label map values to
  1739     /// std::string.
  1740     template <typename Map, typename Converter>
  1741     GraphReader& useEdges(const Map& map, 
  1742 			    const Converter& converter = Converter()) {
  1743       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
  1744       LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 
  1745       _use_edges = true;
  1746       for (EdgeIt a(_graph); a != INVALID; ++a) {
  1747 	_edge_index.insert(std::make_pair(converter(map[a]), a));
  1748       }
  1749       return *this;
  1750     }
  1751 
  1752     /// \brief Skips the reading of node section
  1753     ///
  1754     /// Omit the reading of the node section. This implies that each node
  1755     /// map reading rule will be abanoned, and the nodes of the graph
  1756     /// will not be constructed, which usually cause that the edge set
  1757     /// could not be read due to lack of node name
  1758     /// resolving. Therefore, the \c skipEdges() should be used too, or
  1759     /// the useNodes() member function should be used to specify the
  1760     /// label of the nodes.
  1761     GraphReader& skipNodes() {
  1762       LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 
  1763       _skip_nodes = true;
  1764       return *this;
  1765     }
  1766 
  1767     /// \brief Skips the reading of edge section
  1768     ///
  1769     /// Omit the reading of the edge section. This implies that each edge
  1770     /// map reading rule will be abanoned, and the edges of the graph
  1771     /// will not be constructed.
  1772     GraphReader& skipEdges() {
  1773       LEMON_ASSERT(!_skip_edges, "Skip edges already set"); 
  1774       _skip_edges = true;
  1775       return *this;
  1776     }
  1777 
  1778     /// @}
  1779 
  1780   private:
  1781 
  1782     bool readLine() {
  1783       std::string str;
  1784       while(++line_num, std::getline(*_is, str)) {
  1785 	line.clear(); line.str(str);
  1786 	char c;
  1787 	if (line >> std::ws >> c && c != '#') {
  1788 	  line.putback(c);
  1789 	  return true;
  1790 	}
  1791       }
  1792       return false;
  1793     }
  1794 
  1795     bool readSuccess() {
  1796       return static_cast<bool>(*_is);
  1797     }
  1798     
  1799     void skipSection() {
  1800       char c;
  1801       while (readSuccess() && line >> c && c != '@') {
  1802 	readLine();
  1803       }
  1804       line.putback(c);
  1805     }
  1806 
  1807     void readNodes() {
  1808 
  1809       std::vector<int> map_index(_node_maps.size());
  1810       int map_num, label_index;
  1811 
  1812       char c;
  1813       if (!readLine() || !(line >> c) || c == '@') {
  1814 	if (readSuccess() && line) line.putback(c);
  1815 	if (!_node_maps.empty()) 
  1816 	  throw DataFormatError("Cannot find map names");
  1817 	return;
  1818       }
  1819       line.putback(c);
  1820       
  1821       {
  1822 	std::map<std::string, int> maps;
  1823 	
  1824 	std::string map;
  1825 	int index = 0;
  1826 	while (_reader_bits::readToken(line, map)) {
  1827 	  if (maps.find(map) != maps.end()) {
  1828 	    std::ostringstream msg;
  1829 	    msg << "Multiple occurence of node map: " << map;
  1830 	    throw DataFormatError(msg.str().c_str());
  1831 	  }
  1832 	  maps.insert(std::make_pair(map, index));
  1833 	  ++index;
  1834 	}
  1835 	
  1836 	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
  1837 	  std::map<std::string, int>::iterator jt = 
  1838 	    maps.find(_node_maps[i].first);
  1839 	  if (jt == maps.end()) {
  1840 	    std::ostringstream msg;
  1841 	    msg << "Map not found in file: " << _node_maps[i].first;
  1842 	    throw DataFormatError(msg.str().c_str());
  1843 	  }
  1844 	  map_index[i] = jt->second;
  1845 	}
  1846 
  1847 	{
  1848 	  std::map<std::string, int>::iterator jt = maps.find("label");
  1849 	  if (jt != maps.end()) {
  1850 	    label_index = jt->second;
  1851 	  } else {
  1852 	    label_index = -1;
  1853 	  }
  1854 	}
  1855 	map_num = maps.size();
  1856       }
  1857 
  1858       while (readLine() && line >> c && c != '@') {
  1859 	line.putback(c);
  1860 
  1861 	std::vector<std::string> tokens(map_num);
  1862 	for (int i = 0; i < map_num; ++i) {
  1863 	  if (!_reader_bits::readToken(line, tokens[i])) {
  1864 	    std::ostringstream msg;
  1865 	    msg << "Column not found (" << i + 1 << ")";
  1866 	    throw DataFormatError(msg.str().c_str());
  1867 	  }
  1868 	}
  1869 	if (line >> std::ws >> c)
  1870 	  throw DataFormatError("Extra character on the end of line");
  1871 	
  1872 	Node n;
  1873 	if (!_use_nodes) {
  1874 	  n = _graph.addNode();
  1875 	  if (label_index != -1) 
  1876 	    _node_index.insert(std::make_pair(tokens[label_index], n));
  1877 	} else {
  1878 	  if (label_index == -1) 
  1879 	    throw DataFormatError("Label map not found in file");
  1880 	  typename std::map<std::string, Node>::iterator it =
  1881 	    _node_index.find(tokens[label_index]);
  1882 	  if (it == _node_index.end()) {
  1883 	    std::ostringstream msg;
  1884 	    msg << "Node with label not found: " << tokens[label_index];
  1885 	    throw DataFormatError(msg.str().c_str());	    
  1886 	  }
  1887 	  n = it->second;
  1888 	}
  1889 
  1890 	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
  1891 	  _node_maps[i].second->set(n, tokens[map_index[i]]);
  1892 	}
  1893 
  1894       }
  1895       if (readSuccess()) {
  1896 	line.putback(c);
  1897       }
  1898     }
  1899 
  1900     void readEdges() {
  1901 
  1902       std::vector<int> map_index(_edge_maps.size());
  1903       int map_num, label_index;
  1904 
  1905       char c;
  1906       if (!readLine() || !(line >> c) || c == '@') {
  1907 	if (readSuccess() && line) line.putback(c);
  1908 	if (!_edge_maps.empty()) 
  1909 	  throw DataFormatError("Cannot find map names");
  1910 	return;
  1911       }
  1912       line.putback(c);
  1913       
  1914       {
  1915 	std::map<std::string, int> maps;
  1916 	
  1917 	std::string map;
  1918 	int index = 0;
  1919 	while (_reader_bits::readToken(line, map)) {
  1920 	  if (maps.find(map) != maps.end()) {
  1921 	    std::ostringstream msg;
  1922 	    msg << "Multiple occurence of edge map: " << map;
  1923 	    throw DataFormatError(msg.str().c_str());
  1924 	  }
  1925 	  maps.insert(std::make_pair(map, index));
  1926 	  ++index;
  1927 	}
  1928 	
  1929 	for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
  1930 	  std::map<std::string, int>::iterator jt = 
  1931 	    maps.find(_edge_maps[i].first);
  1932 	  if (jt == maps.end()) {
  1933 	    std::ostringstream msg;
  1934 	    msg << "Map not found in file: " << _edge_maps[i].first;
  1935 	    throw DataFormatError(msg.str().c_str());
  1936 	  }
  1937 	  map_index[i] = jt->second;
  1938 	}
  1939 
  1940 	{
  1941 	  std::map<std::string, int>::iterator jt = maps.find("label");
  1942 	  if (jt != maps.end()) {
  1943 	    label_index = jt->second;
  1944 	  } else {
  1945 	    label_index = -1;
  1946 	  }
  1947 	}
  1948 	map_num = maps.size();
  1949       }
  1950 
  1951       while (readLine() && line >> c && c != '@') {
  1952 	line.putback(c);
  1953 
  1954 	std::string source_token;
  1955 	std::string target_token;
  1956 
  1957 	if (!_reader_bits::readToken(line, source_token))
  1958 	  throw DataFormatError("Node u not found");
  1959 
  1960 	if (!_reader_bits::readToken(line, target_token))
  1961 	  throw DataFormatError("Node v not found");
  1962 	
  1963 	std::vector<std::string> tokens(map_num);
  1964 	for (int i = 0; i < map_num; ++i) {
  1965 	  if (!_reader_bits::readToken(line, tokens[i])) {
  1966 	    std::ostringstream msg;
  1967 	    msg << "Column not found (" << i + 1 << ")";
  1968 	    throw DataFormatError(msg.str().c_str());
  1969 	  }
  1970 	}
  1971 	if (line >> std::ws >> c)
  1972 	  throw DataFormatError("Extra character on the end of line");
  1973 	
  1974 	Edge e;
  1975 	if (!_use_edges) {
  1976 
  1977           typename NodeIndex::iterator it;
  1978  
  1979           it = _node_index.find(source_token);
  1980           if (it == _node_index.end()) {
  1981             std::ostringstream msg;
  1982             msg << "Item not found: " << source_token;
  1983             throw DataFormatError(msg.str().c_str());
  1984           }
  1985           Node source = it->second;
  1986 
  1987           it = _node_index.find(target_token);
  1988           if (it == _node_index.end()) {       
  1989             std::ostringstream msg;            
  1990             msg << "Item not found: " << target_token;
  1991             throw DataFormatError(msg.str().c_str());
  1992           }                                          
  1993           Node target = it->second;                            
  1994 
  1995 	  e = _graph.addEdge(source, target);
  1996 	  if (label_index != -1) 
  1997 	    _edge_index.insert(std::make_pair(tokens[label_index], e));
  1998 	} else {
  1999 	  if (label_index == -1) 
  2000 	    throw DataFormatError("Label map not found in file");
  2001 	  typename std::map<std::string, Edge>::iterator it =
  2002 	    _edge_index.find(tokens[label_index]);
  2003 	  if (it == _edge_index.end()) {
  2004 	    std::ostringstream msg;
  2005 	    msg << "Edge with label not found: " << tokens[label_index];
  2006 	    throw DataFormatError(msg.str().c_str());	    
  2007 	  }
  2008 	  e = it->second;
  2009 	}
  2010 
  2011 	for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
  2012 	  _edge_maps[i].second->set(e, tokens[map_index[i]]);
  2013 	}
  2014 
  2015       }
  2016       if (readSuccess()) {
  2017 	line.putback(c);
  2018       }
  2019     }
  2020 
  2021     void readAttributes() {
  2022 
  2023       std::set<std::string> read_attr;
  2024 
  2025       char c;
  2026       while (readLine() && line >> c && c != '@') {
  2027 	line.putback(c);
  2028 	
  2029 	std::string attr, token;
  2030 	if (!_reader_bits::readToken(line, attr))
  2031 	  throw DataFormatError("Attribute name not found");
  2032 	if (!_reader_bits::readToken(line, token))
  2033 	  throw DataFormatError("Attribute value not found");
  2034 	if (line >> c)
  2035 	  throw DataFormatError("Extra character on the end of line");	  
  2036 
  2037 	{
  2038 	  std::set<std::string>::iterator it = read_attr.find(attr);
  2039 	  if (it != read_attr.end()) {
  2040 	    std::ostringstream msg;
  2041 	    msg << "Multiple occurence of attribute " << attr;
  2042 	    throw DataFormatError(msg.str().c_str());
  2043 	  }
  2044 	  read_attr.insert(attr);
  2045 	}
  2046 	
  2047 	{
  2048 	  typename Attributes::iterator it = _attributes.lower_bound(attr);
  2049 	  while (it != _attributes.end() && it->first == attr) {
  2050 	    it->second->set(token);
  2051 	    ++it;
  2052 	  }
  2053 	}
  2054 
  2055       }
  2056       if (readSuccess()) {
  2057 	line.putback(c);
  2058       }
  2059       for (typename Attributes::iterator it = _attributes.begin();
  2060 	   it != _attributes.end(); ++it) {
  2061 	if (read_attr.find(it->first) == read_attr.end()) {
  2062 	  std::ostringstream msg;
  2063 	  msg << "Attribute not found in file: " << it->first;
  2064 	  throw DataFormatError(msg.str().c_str());
  2065 	}	
  2066       }
  2067     }
  2068 
  2069   public:
  2070 
  2071     /// \name Execution of the reader    
  2072     /// @{
  2073 
  2074     /// \brief Start the batch processing
  2075     ///
  2076     /// This function starts the batch processing
  2077     void run() {
  2078       
  2079       LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
  2080       
  2081       bool nodes_done = _skip_nodes;
  2082       bool edges_done = _skip_edges;
  2083       bool attributes_done = false;
  2084       std::set<std::string> extra_sections;
  2085 
  2086       line_num = 0;      
  2087       readLine();
  2088       skipSection();
  2089 
  2090       while (readSuccess()) {
  2091 	try {
  2092 	  char c;
  2093 	  std::string section, caption;
  2094 	  line >> c;
  2095 	  _reader_bits::readToken(line, section);
  2096 	  _reader_bits::readToken(line, caption);
  2097 
  2098 	  if (line >> c) 
  2099 	    throw DataFormatError("Extra character on the end of line");
  2100 
  2101 	  if (section == "nodes" && !nodes_done) {
  2102 	    if (_nodes_caption.empty() || _nodes_caption == caption) {
  2103 	      readNodes();
  2104 	      nodes_done = true;
  2105 	    }
  2106 	  } else if ((section == "edges" || section == "arcs") && 
  2107 		     !edges_done) {
  2108 	    if (_edges_caption.empty() || _edges_caption == caption) {
  2109 	      readEdges();
  2110 	      edges_done = true;
  2111 	    }
  2112 	  } else if (section == "attributes" && !attributes_done) {
  2113 	    if (_attributes_caption.empty() || _attributes_caption == caption) {
  2114 	      readAttributes();
  2115 	      attributes_done = true;
  2116 	    }
  2117 	  } else {
  2118 	    if (extra_sections.find(section) != extra_sections.end()) {
  2119 	      std::ostringstream msg;
  2120 	      msg << "Multiple occurence of section " << section;
  2121 	      throw DataFormatError(msg.str().c_str());
  2122 	    }
  2123 	    Sections::iterator it = _sections.find(section);
  2124 	    if (it != _sections.end()) {
  2125 	      extra_sections.insert(section);
  2126 	      it->second->process(*_is, line_num);
  2127 	    }
  2128 	    readLine();
  2129 	    skipSection();
  2130 	  }
  2131 	} catch (DataFormatError& error) {
  2132 	  error.line(line_num);
  2133 	  throw;
  2134 	}	
  2135       }
  2136 
  2137       if (!nodes_done) {
  2138 	throw DataFormatError("Section @nodes not found");
  2139       }
  2140 
  2141       if (!edges_done) {
  2142 	throw DataFormatError("Section @edges not found");
  2143       }
  2144 
  2145       if (!attributes_done && !_attributes.empty()) {
  2146 	throw DataFormatError("Section @attributes not found");
  2147       }
  2148 
  2149     }
  2150 
  2151     /// @}
  2152     
  2153   };
  2154 
  2155   /// \relates GraphReader
  2156   template <typename Graph>
  2157   GraphReader<Graph> graphReader(std::istream& is, Graph& graph) {
  2158     GraphReader<Graph> tmp(is, graph);
  2159     return tmp;
  2160   }
  2161 
  2162   /// \relates GraphReader
  2163   template <typename Graph>
  2164   GraphReader<Graph> graphReader(const std::string& fn, 
  2165 				       Graph& graph) {
  2166     GraphReader<Graph> tmp(fn, graph);
  2167     return tmp;
  2168   }
  2169 
  2170   /// \relates GraphReader
  2171   template <typename Graph>
  2172   GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
  2173     GraphReader<Graph> tmp(fn, graph);
  2174     return tmp;
  2175   }
  2176 
  2177   /// \ingroup lemon_io
  2178   ///
  2179   /// \brief Reader for the contents of the \ref lgf-format "LGF" file 
  2180   ///
  2181   /// This class can be used to read the sections, the map names and
  2182   /// the attributes from a file. Usually, the Lemon programs know
  2183   /// that, which type of graph, which maps and which attributes
  2184   /// should be read from a file, but in general tools (like glemon)
  2185   /// the contents of an LGF file should be guessed somehow. This class
  2186   /// reads the graph and stores the appropriate information for
  2187   /// reading the graph.
  2188   ///
  2189   ///\code LgfContents contents("graph.lgf"); 
  2190   /// contents.run();
  2191   ///
  2192   /// // does it contain any node section and arc section
  2193   /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
  2194   ///   std::cerr << "Failure, cannot find graph" << std::endl;
  2195   ///   return -1;
  2196   /// }
  2197   /// std::cout << "The name of the default node section : " 
  2198   ///           << contents.nodeSection(0) << std::endl;
  2199   /// std::cout << "The number of the arc maps : " 
  2200   ///           << contents.arcMaps(0).size() << std::endl;
  2201   /// std::cout << "The name of second arc map : " 
  2202   ///           << contents.arcMaps(0)[1] << std::endl;
  2203   ///\endcode
  2204   class LgfContents {    
  2205   private:
  2206 
  2207     std::istream* _is;
  2208     bool local_is;
  2209 
  2210     std::vector<std::string> _node_sections;
  2211     std::vector<std::string> _edge_sections;
  2212     std::vector<std::string> _attribute_sections;
  2213     std::vector<std::string> _extra_sections;
  2214 
  2215     std::vector<bool> _arc_sections;
  2216 
  2217     std::vector<std::vector<std::string> > _node_maps;
  2218     std::vector<std::vector<std::string> > _edge_maps;
  2219 
  2220     std::vector<std::vector<std::string> > _attributes;
  2221 
  2222 
  2223     int line_num;
  2224     std::istringstream line;
  2225     
  2226   public:
  2227 
  2228     /// \brief Constructor
  2229     ///
  2230     /// Construct an \e LGF contents reader, which reads from the given
  2231     /// input stream.
  2232     LgfContents(std::istream& is) 
  2233       : _is(&is), local_is(false) {}
  2234 
  2235     /// \brief Constructor
  2236     ///
  2237     /// Construct an \e LGF contents reader, which reads from the given
  2238     /// file.
  2239     LgfContents(const std::string& fn) 
  2240       : _is(new std::ifstream(fn.c_str())), local_is(true) {}
  2241 
  2242     /// \brief Constructor
  2243     ///
  2244     /// Construct an \e LGF contents reader, which reads from the given
  2245     /// file.
  2246     LgfContents(const char* fn)
  2247       : _is(new std::ifstream(fn)), local_is(true) {}
  2248 
  2249     /// \brief Copy constructor
  2250     ///
  2251     /// The copy constructor transfers all data from the other reader,
  2252     /// therefore the copied reader will not be usable more. 
  2253     LgfContents(LgfContents& other)
  2254       : _is(other._is), local_is(other.local_is) {
  2255       
  2256       other._is = 0;
  2257       other.local_is = false;
  2258       
  2259       _node_sections.swap(other._node_sections);
  2260       _edge_sections.swap(other._edge_sections);
  2261       _attribute_sections.swap(other._attribute_sections);
  2262       _extra_sections.swap(other._extra_sections);
  2263 
  2264       _arc_sections.swap(other._arc_sections);
  2265 
  2266       _node_maps.swap(other._node_maps);
  2267       _edge_maps.swap(other._edge_maps);
  2268       _attributes.swap(other._attributes);
  2269     }
  2270     
  2271     /// \brief Destructor
  2272     ~LgfContents() {
  2273       if (local_is) delete _is;
  2274     }
  2275 
  2276 
  2277     /// \name Node sections
  2278     /// @{
  2279 
  2280     /// \brief Gives back the number of node sections in the file.
  2281     ///
  2282     /// Gives back the number of node sections in the file.
  2283     int nodeSectionNum() const {
  2284       return _node_sections.size();
  2285     }
  2286 
  2287     /// \brief Returns the section name at the given position. 
  2288     ///
  2289     /// Returns the section name at the given position. 
  2290     const std::string& nodeSection(int i) const {
  2291       return _node_sections[i];
  2292     }
  2293 
  2294     /// \brief Gives back the node maps for the given section.
  2295     ///
  2296     /// Gives back the node maps for the given section.
  2297     const std::vector<std::string>& nodeMapNames(int i) const {
  2298       return _node_maps[i];
  2299     }
  2300 
  2301     /// @}
  2302 
  2303     /// \name Arc/Edge sections 
  2304     /// @{
  2305 
  2306     /// \brief Gives back the number of arc/edge sections in the file.
  2307     ///
  2308     /// Gives back the number of arc/edge sections in the file.
  2309     /// \note It is synonym of \c edgeSectionNum().
  2310     int arcSectionNum() const {
  2311       return _edge_sections.size();
  2312     }
  2313 
  2314     /// \brief Returns the section name at the given position. 
  2315     ///
  2316     /// Returns the section name at the given position. 
  2317     /// \note It is synonym of \c edgeSection().
  2318     const std::string& arcSection(int i) const {
  2319       return _edge_sections[i];
  2320     }
  2321 
  2322     /// \brief Gives back the arc/edge maps for the given section.
  2323     ///
  2324     /// Gives back the arc/edge maps for the given section.
  2325     /// \note It is synonym of \c edgeMapNames().
  2326     const std::vector<std::string>& arcMapNames(int i) const {
  2327       return _edge_maps[i];
  2328     }
  2329 
  2330     /// @}
  2331 
  2332     /// \name Synonyms
  2333     /// @{
  2334 
  2335     /// \brief Gives back the number of arc/edge sections in the file.
  2336     ///
  2337     /// Gives back the number of arc/edge sections in the file.
  2338     /// \note It is synonym of \c arcSectionNum().
  2339     int edgeSectionNum() const {
  2340       return _edge_sections.size();
  2341     }
  2342 
  2343     /// \brief Returns the section name at the given position. 
  2344     ///
  2345     /// Returns the section name at the given position. 
  2346     /// \note It is synonym of \c arcSection().
  2347     const std::string& edgeSection(int i) const {
  2348       return _edge_sections[i];
  2349     }
  2350 
  2351     /// \brief Gives back the edge maps for the given section.
  2352     ///
  2353     /// Gives back the edge maps for the given section.
  2354     /// \note It is synonym of \c arcMapNames().
  2355     const std::vector<std::string>& edgeMapNames(int i) const {
  2356       return _edge_maps[i];
  2357     }
  2358 
  2359     /// @}
  2360 
  2361     /// \name Attribute sections   
  2362     /// @{
  2363 
  2364     /// \brief Gives back the number of attribute sections in the file.
  2365     ///
  2366     /// Gives back the number of attribute sections in the file.
  2367     int attributeSectionNum() const {
  2368       return _attribute_sections.size();
  2369     }
  2370 
  2371     /// \brief Returns the section name at the given position. 
  2372     ///
  2373     /// Returns the section name at the given position. 
  2374     const std::string& attributeSectionNames(int i) const {
  2375       return _attribute_sections[i];
  2376     }
  2377 
  2378     /// \brief Gives back the attributes for the given section.
  2379     ///
  2380     /// Gives back the attributes for the given section.
  2381     const std::vector<std::string>& attributes(int i) const {
  2382       return _attributes[i];
  2383     }
  2384 
  2385     /// @}
  2386 
  2387     /// \name Extra sections   
  2388     /// @{
  2389 
  2390     /// \brief Gives back the number of extra sections in the file.
  2391     ///
  2392     /// Gives back the number of extra sections in the file.
  2393     int extraSectionNum() const {
  2394       return _extra_sections.size();
  2395     }
  2396 
  2397     /// \brief Returns the extra section type at the given position. 
  2398     ///
  2399     /// Returns the section type at the given position. 
  2400     const std::string& extraSection(int i) const {
  2401       return _extra_sections[i];
  2402     }
  2403 
  2404     /// @}
  2405 
  2406   private:
  2407 
  2408     bool readLine() {
  2409       std::string str;
  2410       while(++line_num, std::getline(*_is, str)) {
  2411 	line.clear(); line.str(str);
  2412 	char c;
  2413 	if (line >> std::ws >> c && c != '#') {
  2414 	  line.putback(c);
  2415 	  return true;
  2416 	}
  2417       }
  2418       return false;
  2419     }
  2420 
  2421     bool readSuccess() {
  2422       return static_cast<bool>(*_is);
  2423     }
  2424 
  2425     void skipSection() {
  2426       char c;
  2427       while (readSuccess() && line >> c && c != '@') {
  2428 	readLine();
  2429       }
  2430       line.putback(c);
  2431     }
  2432 
  2433     void readMaps(std::vector<std::string>& maps) {
  2434       char c;
  2435       if (!readLine() || !(line >> c) || c == '@') {
  2436 	if (readSuccess() && line) line.putback(c);
  2437 	return;
  2438       }
  2439       line.putback(c);
  2440       std::string map;
  2441       while (_reader_bits::readToken(line, map)) {
  2442 	maps.push_back(map);
  2443       }
  2444     }
  2445 
  2446     void readAttributes(std::vector<std::string>& attrs) {
  2447       readLine();
  2448       char c;
  2449       while (readSuccess() && line >> c && c != '@') {
  2450 	line.putback(c);
  2451 	std::string attr;
  2452 	_reader_bits::readToken(line, attr);
  2453 	attrs.push_back(attr);
  2454 	readLine();
  2455       }
  2456       line.putback(c);
  2457     }
  2458 
  2459   public:
  2460 
  2461     /// \name Execution of the contents reader    
  2462     /// @{
  2463 
  2464     /// \brief Start the reading
  2465     ///
  2466     /// This function starts the reading
  2467     void run() {
  2468 
  2469       readLine();
  2470       skipSection();
  2471 
  2472       while (readSuccess()) {
  2473 
  2474 	char c;
  2475 	line >> c;
  2476 
  2477 	std::string section, caption;
  2478 	_reader_bits::readToken(line, section);
  2479 	_reader_bits::readToken(line, caption);
  2480 
  2481 	if (section == "nodes") {
  2482 	  _node_sections.push_back(caption);
  2483 	  _node_maps.push_back(std::vector<std::string>());
  2484 	  readMaps(_node_maps.back());
  2485 	  readLine(); skipSection();
  2486 	} else if (section == "arcs" || section == "edges") {
  2487 	  _edge_sections.push_back(caption);
  2488 	  _arc_sections.push_back(section == "arcs");
  2489 	  _edge_maps.push_back(std::vector<std::string>());
  2490 	  readMaps(_edge_maps.back());
  2491 	  readLine(); skipSection();
  2492 	} else if (section == "attributes") {
  2493 	  _attribute_sections.push_back(caption);
  2494 	  _attributes.push_back(std::vector<std::string>());
  2495 	  readAttributes(_attributes.back());
  2496 	} else {
  2497 	  _extra_sections.push_back(section);
  2498 	  readLine(); skipSection();
  2499 	}
  2500       }
  2501     }
  2502 
  2503     /// @}
  2504     
  2505   };
  2506 }
  2507 
  2508 #endif