lemon/lemon_reader.h
author deba
Wed, 24 Oct 2007 16:31:49 +0000
changeset 2502 9c23c3762bc5
parent 2476 059dcdda37c5
child 2504 46a82ce84cc6
permissions -rw-r--r--
BpUGraphReader and Writer
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2007
     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 Format reader.
    22 
    23 
    24 #ifndef LEMON_LEMON_READER_H
    25 #define LEMON_LEMON_READER_H
    26 
    27 
    28 #include <iostream>
    29 #include <fstream>
    30 #include <string>
    31 #include <vector>
    32 #include <algorithm>
    33 #include <map>
    34 #include <memory>
    35 
    36 #include <lemon/error.h>
    37 #include <lemon/graph_utils.h>
    38 #include <lemon/bits/utility.h>
    39 #include <lemon/bits/item_reader.h>
    40 
    41 #include <lemon/dim2.h>
    42 
    43 #include <lemon/concept_check.h>
    44 #include <lemon/concepts/maps.h>
    45 
    46 namespace lemon {
    47 
    48   namespace _reader_bits {
    49 
    50     template <typename T>
    51     bool operator<(T, T) {
    52       throw DataFormatError("Label is not comparable");
    53     }
    54 
    55     template <typename T>
    56     struct Less {
    57       bool operator()(const T& p, const T& q) const {
    58 	return p < q;
    59       }
    60     };
    61     
    62     template <typename Item>
    63     class ItemLabelReader {
    64     public:
    65 
    66       bool isLabelReader() { return true; }
    67 
    68       void readLabel(std::istream&, Item&) {}
    69       
    70       template <class _ItemLabelReader>
    71       struct Constraints {
    72 	void constraints() {
    73 	  bool b = reader.isLabelReader();
    74 	  ignore_unused_variable_warning(b);
    75 	  Item item;
    76 	  reader.readLabel(is, item);
    77 	}
    78 	_ItemLabelReader& reader;
    79 	std::istream& is;
    80       };
    81 
    82     };
    83 
    84     template <typename Item>
    85     class ItemReader {
    86     public:
    87       void read(std::istream&, Item&) {}
    88       
    89       template <class _ItemReader>
    90       struct Constraints {
    91 	void constraints() {
    92 	  Item item;
    93 	  reader.read(is, item);
    94 	}
    95 	_ItemReader& reader;
    96 	std::istream& is;
    97       };
    98 
    99     };
   100 
   101     template <typename Map>
   102     struct Ref { typedef Map& Type; };
   103     template <typename Map>
   104     struct Arg { typedef Map& Type; };
   105 
   106     template <typename Graph, typename Map>
   107     class ForwardComposeMap {
   108     public:
   109       typedef typename Graph::UEdge Key;
   110       typedef typename Map::Value Value;
   111 
   112       ForwardComposeMap(const Graph& _graph, typename Arg<Map>::Type _map) 
   113 	: graph(_graph), map(_map) {}
   114       
   115       void set(const Key& key, const Value& val) {
   116 	map.set(graph.direct(key, true), val);
   117       }
   118 
   119     private:
   120       const Graph& graph;
   121       typename Ref<Map>::Type map;
   122     };
   123 
   124     template <typename Graph, typename Map>
   125     ForwardComposeMap<Graph, Map>
   126     forwardComposeMap(const Graph& graph, const Map& map) {
   127       return ForwardComposeMap<Graph, Map>(graph, map);
   128     }
   129 
   130     template <typename Graph, typename Map>
   131     ForwardComposeMap<Graph, Map>
   132     forwardComposeMap(const Graph& graph, Map& map) {
   133       return ForwardComposeMap<Graph, Map>(graph, map);
   134     }
   135 
   136     template <typename Graph, typename Map>
   137     class BackwardComposeMap {
   138     public:
   139       typedef typename Graph::UEdge Key;
   140       typedef typename Map::Value Value;
   141 
   142       BackwardComposeMap(const Graph& _graph, typename Arg<Map>::Type _map) 
   143 	: graph(_graph), map(_map) {}
   144       
   145       void set(const Key& key, const Value& val) {
   146 	map.set(graph.direct(key, false), val);
   147       }
   148 
   149     private:
   150       const Graph& graph;
   151       typename Ref<Map>::Type map;
   152     };
   153 
   154 
   155     template <typename Graph, typename Map>
   156     BackwardComposeMap<Graph, Map>
   157     backwardComposeMap(const Graph& graph, const Map& map) {
   158       return BackwardComposeMap<Graph, Map>(graph, map);
   159     }
   160 
   161     template <typename Graph, typename Map>
   162     BackwardComposeMap<Graph, Map>
   163     backwardComposeMap(const Graph& graph, Map& map) {
   164       return BackwardComposeMap<Graph, Map>(graph, map);
   165     }
   166 
   167     template <typename Graph, typename Map>
   168     struct Ref<ForwardComposeMap<Graph, Map> > { 
   169       typedef ForwardComposeMap<Graph, Map> Type;
   170     };
   171     template <typename Graph, typename Map>
   172     struct Arg<ForwardComposeMap<Graph, Map> > { 
   173       typedef const ForwardComposeMap<Graph, Map>& Type;
   174     };
   175 
   176     template <typename Graph, typename Map>
   177     struct Ref<BackwardComposeMap<Graph, Map> > { 
   178       typedef BackwardComposeMap<Graph, Map> Type; 
   179     };
   180     template <typename Graph, typename Map>
   181     struct Arg<BackwardComposeMap<Graph, Map> > { 
   182       typedef const BackwardComposeMap<Graph, Map>& Type; 
   183     };
   184 
   185     template <typename Map>
   186     struct Ref<dim2::XMap<Map> > { 
   187       typedef dim2::XMap<Map> Type;
   188     };
   189     template <typename Map>
   190     struct Arg<dim2::XMap<Map> > { 
   191       typedef const dim2::XMap<Map>& Type;
   192     };
   193 
   194     template <typename Map>
   195     struct Ref<dim2::YMap<Map> > { 
   196       typedef dim2::YMap<Map> Type;
   197     };
   198     template <typename Map>
   199     struct Arg<dim2::YMap<Map> > { 
   200       typedef const dim2::YMap<Map>& Type;
   201     };
   202 
   203 
   204     template <typename _Item>
   205     class MapReaderBase;
   206     
   207     template <typename _Item>
   208     class MapInverterBase : public MapReaderBase<_Item> {
   209     public:
   210       typedef _Item Item;
   211       virtual void read(std::istream&, const Item&) = 0;
   212       virtual Item read(std::istream&) const = 0;
   213 
   214       virtual MapInverterBase<_Item>* getInverter() {
   215 	return this;
   216       }
   217     };
   218 
   219     template <typename _Item, typename _Map, typename _Reader>
   220     class MapReaderInverter : public MapInverterBase<_Item> {
   221     public:
   222       typedef _Item Item;
   223       typedef _Reader Reader;
   224       typedef typename Reader::Value Value;
   225       typedef _Map Map;
   226       typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
   227 
   228       typename _reader_bits::Ref<Map>::Type map;
   229       Reader reader;
   230       Inverse inverse;
   231 
   232       MapReaderInverter(typename _reader_bits::Arg<Map>::Type _map,
   233 			const Reader& _reader) 
   234 	: map(_map), reader(_reader) {}
   235 
   236       virtual ~MapReaderInverter() {}
   237 
   238       virtual void read(std::istream& is, const Item& item) {
   239 	Value value;
   240 	reader.read(is, value);
   241 	map.set(item, value);
   242 	typename Inverse::iterator it = inverse.find(value);
   243 	if (it == inverse.end()) {
   244 	  inverse.insert(std::make_pair(value, item));
   245 	} else {
   246 	  throw DataFormatError("Multiple label occurence");
   247 	}
   248       }
   249 
   250       virtual Item read(std::istream& is) const {
   251 	Value value;
   252 	reader.read(is, value);	
   253 	typename Inverse::const_iterator it = inverse.find(value);
   254 	if (it != inverse.end()) {
   255 	  return it->second;
   256 	} else {
   257 	  ErrorMessage msg;
   258 	  msg << "Invalid label error"; 
   259 	  throw DataFormatError(msg.message());
   260 	}
   261       }      
   262     };
   263 
   264     template <typename _Item, typename _Reader>
   265     class SkipReaderInverter : public MapInverterBase<_Item> {
   266     public:
   267       typedef _Item Item;
   268       typedef _Reader Reader;
   269       typedef typename Reader::Value Value;
   270       typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
   271 
   272       Reader reader;
   273 
   274       SkipReaderInverter(const Reader& _reader) 
   275 	: reader(_reader) {}
   276 
   277       virtual ~SkipReaderInverter() {}
   278 
   279       virtual void read(std::istream& is, const Item& item) {
   280 	Value value;
   281 	reader.read(is, value);
   282 	typename Inverse::iterator it = inverse.find(value);
   283 	if (it == inverse.end()) {
   284 	  inverse.insert(std::make_pair(value, item));
   285 	} else {
   286 	  throw DataFormatError("Multiple label occurence error");
   287 	}
   288       }
   289 
   290       virtual Item read(std::istream& is) const {
   291 	Value value;
   292 	reader.read(is, value);
   293 	typename Inverse::const_iterator it = inverse.find(value);
   294 	if (it != inverse.end()) {
   295 	  return it->second;
   296 	} else {
   297 	  ErrorMessage msg;
   298 	  msg << "Invalid label error: " << value; 
   299 	  throw DataFormatError(msg.message());
   300 	}
   301       }
   302 
   303     private:
   304       Inverse inverse;
   305     };
   306 
   307     template <typename _Item>    
   308     class MapReaderBase {
   309     public:
   310       typedef _Item Item;
   311 
   312       MapReaderBase() { _touched = false; }
   313       
   314       void touch(bool value = true) { _touched = value; }
   315       bool touched() const { return _touched; }
   316 
   317       virtual ~MapReaderBase() {}
   318 
   319       virtual void read(std::istream& is, const Item& item) = 0;
   320       virtual MapInverterBase<_Item>* getInverter() = 0;
   321 
   322     private:      
   323       bool _touched;
   324 
   325     };
   326 
   327     template <typename _Item, typename _Map, typename _Reader>
   328     class MapReader : public MapReaderBase<_Item> {
   329     public:
   330       typedef _Map Map;
   331       typedef _Reader Reader;
   332       typedef typename Reader::Value Value;
   333       typedef _Item Item;
   334       
   335       typename _reader_bits::Ref<Map>::Type map;
   336       Reader reader;
   337 
   338       MapReader(typename _reader_bits::Arg<Map>::Type _map, 
   339 		const Reader& _reader) 
   340 	: map(_map), reader(_reader) {}
   341 
   342       virtual ~MapReader() {}
   343 
   344       virtual void read(std::istream& is, const Item& item) {
   345 	Value value;
   346 	reader.read(is, value);
   347 	map.set(item, value);
   348       }
   349 
   350       virtual MapInverterBase<_Item>* getInverter() {
   351 	return new MapReaderInverter<Item, Map, Reader>(map, reader);
   352       }
   353     };
   354 
   355 
   356     template <typename _Item, typename _Reader>
   357     class SkipReader : public MapReaderBase<_Item> {
   358     public:
   359       typedef _Reader Reader;
   360       typedef typename Reader::Value Value;
   361       typedef _Item Item;
   362 
   363       Reader reader;
   364       SkipReader(const Reader& _reader) : reader(_reader) {}
   365 
   366       virtual ~SkipReader() {}
   367 
   368       virtual void read(std::istream& is, const Item&) {
   369 	Value value;
   370 	reader.read(is, value);
   371       }      
   372 
   373       virtual MapInverterBase<Item>* getInverter() {
   374 	return new SkipReaderInverter<Item, Reader>(reader);
   375       }
   376     };
   377 
   378     template <typename _Item>
   379     class LabelReaderBase {
   380     public:
   381       typedef _Item Item;
   382       virtual ~LabelReaderBase() {}
   383       virtual Item read(std::istream& is) const = 0;
   384       virtual bool isLabelReader() const = 0;
   385       virtual LabelReaderBase<_Item>* clone() const = 0;
   386     };
   387 
   388     template <typename _Item, typename _BoxedLabelReader>
   389     class LabelReader : public LabelReaderBase<_Item> {
   390     public:
   391       typedef _Item Item;
   392       typedef _BoxedLabelReader BoxedLabelReader;
   393       
   394       const BoxedLabelReader& labelReader;
   395 
   396       LabelReader(const BoxedLabelReader& _labelReader) 
   397 	: labelReader(_labelReader) {}
   398 
   399       virtual Item read(std::istream& is) const {
   400 	Item item;
   401 	labelReader.readLabel(is, item);
   402 	return item;
   403       }
   404 
   405       virtual bool isLabelReader() const {
   406 	return labelReader.isLabelReader();
   407       }
   408       
   409       LabelReader<Item, BoxedLabelReader>* clone() const {
   410 	return new LabelReader<Item, BoxedLabelReader>(labelReader);
   411       }
   412     };
   413 
   414     template <typename _Item>
   415     class ItemStore {
   416     public:
   417 
   418       typedef _Item Item;
   419 
   420       ItemStore(Item& _item) : item(&_item) { 
   421 	_touched = false; 
   422       }
   423       
   424       void touch() { _touched = true; }
   425       bool touched() const { return _touched; }
   426 
   427       void read(const Item& _item) {
   428 	*item = _item;
   429       }
   430       
   431     private:
   432       Item* item;
   433       bool _touched;
   434     };
   435 
   436     class ValueReaderBase {
   437     public:
   438       virtual void read(std::istream&) {};
   439       ValueReaderBase() { _touched = false; }
   440 
   441       void touch() { _touched = true; }
   442       bool touched() const { return _touched; }
   443 
   444       virtual ~ValueReaderBase() {}
   445     private:
   446       bool _touched;
   447     };
   448 
   449     template <typename _Value, typename _Reader>
   450     class ValueReader : public ValueReaderBase {
   451     public:
   452       typedef _Value Value;
   453       typedef _Reader Reader;
   454 
   455       ValueReader(Value& _value, const Reader& _reader)
   456  	: value(_value), reader(_reader) {}
   457 
   458       virtual void read(std::istream& is) {
   459 	reader.read(is, value);
   460       }
   461     private:
   462       Value& value;
   463       Reader reader;
   464     };
   465 
   466   }
   467 
   468   /// \ingroup lemon_io
   469   /// \brief Lemon Format reader class.
   470   /// 
   471   /// The Lemon Format contains several sections. We do not want to
   472   /// determine what sections are in a lemon file we give only a framework
   473   /// to read a section oriented format.
   474   ///
   475   /// In the Lemon Format each section starts with a line containing a
   476   /// \c \@ character on the first not white space position. This line
   477   /// is the header line of the section. Each of the next lines belong
   478   /// to this section until a line starting with \c \@ character is
   479   /// found. This line can start a new section or it can close the
   480   /// file with the \c \@end line.  The file format ignores the empty
   481   /// and comment lines. The line is comment line if it starts with a
   482   /// \c # character.
   483   ///
   484   /// The framework provides an abstract LemonReader::SectionReader class
   485   /// that defines the interface of a SectionReader. The SectionReader
   486   /// has the \c header() member function that gets a header line string and
   487   /// decides if it wants to process the next section. Several SectionReaders
   488   /// can be attached to a LemonReader and the first attached that can
   489   /// process the section will be used. Its \c read() member will be called
   490   /// with a stream containing the section. From this stream the empty and
   491   /// comment lines are filtered out.
   492   ///
   493   /// \relates GraphReader
   494   /// \relates NodeSetReader
   495   /// \relates EdgeSetReader
   496   /// \relates NodesReader
   497   /// \relates EdgesReader
   498   /// \relates AttributeReader
   499   class LemonReader {
   500   private:
   501     
   502     class FilterStreamBuf : public std::streambuf {
   503     public:
   504 
   505       typedef std::streambuf Parent;
   506       typedef Parent::char_type char_type;
   507       FilterStreamBuf(std::istream& is, int& num) 
   508 	: _is(is), _base(0), _eptr(0), 
   509 	  _num(num), skip_state(after_endl) {}
   510 
   511     protected:
   512 
   513       enum skip_state_type {
   514 	no_skip,
   515 	after_endl,
   516 	comment_line
   517       };
   518 
   519       char_type small_buf[1];
   520 
   521 
   522       std::istream& _is;
   523 
   524       char_type* _base;
   525       char_type* _eptr;
   526 
   527       int& _num;
   528 
   529       skip_state_type skip_state;
   530 
   531 
   532       char_type* base() { return _base; }
   533 
   534       char_type* eptr() { return _eptr; }
   535 
   536       int_type blen() { return _eptr - _base; }
   537 
   538       void setb(char_type* buf, int_type len) {
   539 	_base = buf;
   540 	_eptr = buf + len;
   541       }
   542   
   543       virtual std::streambuf* setbuf(char *buf, std::streamsize len) {
   544 	if (base()) return 0;
   545 	if (buf != 0 && len >= int(sizeof(small_buf))) {
   546 	  setb(buf, len);
   547 	} else {
   548 	  setb(small_buf, sizeof(small_buf));
   549 	}
   550 	setg(0, 0, 0);
   551 	return this;
   552       }
   553 
   554       bool put_char(char c) {
   555 	switch (skip_state) {
   556 	case no_skip:
   557 	  switch (c) {
   558 	  case '\n': 
   559 	    skip_state = after_endl;
   560 	    return true;
   561 	  default:
   562 	    return true;
   563 	  }
   564 	case after_endl:
   565 	  switch (c) {
   566 	  case '@':
   567 	    return false;
   568 	  case '\n': 
   569 	    return false;
   570 	  case '#':
   571 	    skip_state = comment_line;
   572 	    return false;
   573 	  default:
   574 	    if (!isspace(c)) {
   575 	      skip_state = no_skip;
   576 	      return true;
   577 	    } else {
   578 	      return false;
   579 	    }
   580 	  }
   581 	  break;
   582 	case comment_line:
   583 	  switch (c) {
   584 	  case '\n': 
   585 	    skip_state = after_endl;
   586 	    return false;
   587 	  default:
   588 	    return false;
   589 	  }
   590 	}
   591 	return false;
   592       }
   593 
   594       virtual int_type underflow() {
   595 	char c;
   596 	if ((c = _is.peek()) != EOF) {
   597 	  if (c == '@') {
   598 	    return EOF;
   599 	  }
   600 	} else {
   601 	  return EOF;
   602 	}
   603 	char_type *ptr;
   604 	for (ptr = base(); ptr != eptr(); ++ptr) {
   605 	  if ((c = _is.get()) != EOF) {
   606 	    if (c == '\n') ++_num;
   607 	    if (put_char(c)) {
   608 	      *ptr = c;
   609 	    } else {
   610 	      if (skip_state == after_endl && c == '@') {
   611 		_is.putback(c);
   612 		break;
   613 	      }
   614 	      --ptr;
   615 	    }
   616 	  } else {
   617 	    break;
   618 	  }
   619 	}
   620 	setg(base(), base(), ptr);
   621 	return *base();
   622       }
   623 
   624       virtual int_type sync() {
   625 	return EOF;
   626       }
   627 
   628     public:
   629 
   630       int line_num() const {
   631 	int r = _num;
   632 	for (char_type* p = gptr(); p != egptr(); ++p) {
   633 	  if (*p == '\n') --r;
   634 	}
   635 	return r;
   636       }
   637 
   638     };
   639 
   640     static void skipPreSection(std::istream& is, int& line_num) {
   641       enum skip_state_type { skip, after_endl };
   642 
   643       skip_state_type skip_state = after_endl;
   644       char c;
   645       
   646       while ((c = is.get()) != EOF) {
   647 	if (c == '\n') ++line_num;
   648 
   649 	switch (skip_state) {
   650 	case skip:
   651 	  if (c == '\n') skip_state = after_endl;
   652 	  break;
   653 	case after_endl:
   654 	  switch (c) {
   655 	  case '@':
   656 	    is.putback(c);
   657 	    return;
   658 	  case '\n':
   659 	    continue;
   660 	  default:
   661 	    if (!isspace(c)) {
   662 	      skip_state = skip;
   663 	    }
   664 	    break;
   665 	  }
   666 	}	
   667       }
   668     }
   669 
   670   public:
   671 
   672     /// \brief Abstract base class for reading a section.
   673     ///
   674     /// This class has an \c header() member function what get a 
   675     /// header line string and decides if it want to process the next 
   676     /// section. Several SectionReaders can be attached to an LemonReader 
   677     /// and the first attached what can process the section will be used. 
   678     /// Its \c read() member will called with a stream contains the section. 
   679     /// From this stream the empty lines and comments are filtered out.
   680     class SectionReader {
   681       friend class LemonReader;
   682     protected:
   683       /// \brief Constructor for SectionReader.
   684       ///
   685       /// Constructor for SectionReader. It attach this reader to
   686       /// the given LemonReader.
   687       SectionReader(LemonReader& reader) {
   688 	reader.attach(*this);
   689       }
   690 
   691       virtual ~SectionReader() {}
   692 
   693       /// \brief Gives back true when the SectionReader can process 
   694       /// the section with the given header line.
   695       ///
   696       /// It gives back true when the SectionReader can process
   697       /// the section with the given header line.
   698       virtual bool header(const std::string& line) = 0;
   699 
   700       /// \brief Reader function of the section.
   701       ///
   702       /// It reads the content of the section.
   703       virtual void read(std::istream& is) = 0;
   704 
   705       /// \brief The given section missing in the file.
   706       ///
   707       /// The given section missing in the file.
   708       virtual void missing() {};
   709     };
   710 
   711     /// \brief Constructor for LemonReader.
   712     ///
   713     /// Constructor for LemonReader which reads from the given stream.
   714     LemonReader(std::istream& _is) 
   715       : is(&_is), own_is(false) {}
   716 
   717     /// \brief Constructor for LemonReader.
   718     ///
   719     /// Constructor for LemonReader which reads from the given file.
   720     LemonReader(const std::string& filename) 
   721       : is(0), own_is(true) {
   722       is = new std::ifstream(filename.c_str());
   723       if (is->fail()) {
   724 	throw FileOpenError(filename);
   725       }
   726     }
   727 
   728     /// \brief Desctructor for LemonReader.
   729     ///
   730     /// Desctructor for LemonReader.
   731     ~LemonReader() {
   732       if (own_is) {
   733 	delete is;
   734       }
   735     }
   736 
   737   private:
   738     LemonReader(const LemonReader&);
   739     void operator=(const LemonReader&);
   740 
   741     void attach(SectionReader& reader) {
   742       readers.push_back(std::make_pair(&reader, false));
   743     }
   744 
   745   public:
   746     /// \brief Executes the LemonReader.
   747     /// 
   748     /// It executes the LemonReader.
   749     void run() {
   750       int line_num = 0;
   751       std::string line;
   752       
   753       SectionReaders::iterator it;
   754       skipPreSection(*is, line_num);
   755       while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
   756 	for (it = readers.begin(); it != readers.end(); ++it) {
   757 	  if (it->first->header(line)) {
   758 	    it->second = true;
   759 	    char buf[2048];
   760 	    FilterStreamBuf buffer(*is, line_num);
   761 	    try {
   762 	      buffer.pubsetbuf(buf, sizeof(buf));
   763 	      std::istream ss(&buffer);
   764 	      it->first->read(ss);
   765 	      skipPreSection(*is, line_num);
   766 	      break;
   767 	    } catch (DataFormatError& error) {
   768 	      error.line(buffer.line_num());
   769 	      throw;
   770 	    }	
   771 	  }
   772 	}
   773       }
   774       for (it = readers.begin(); it != readers.end(); ++it) {
   775 	if (!it->second) {
   776 	  try {
   777 	    it->first->missing();
   778 	  } catch (DataFormatError& error) {
   779 	    error.line(line_num);
   780 	    throw;
   781 	  }	
   782 	}
   783       }
   784     }
   785 
   786 
   787   private:
   788 
   789     std::istream* is;
   790     bool own_is;
   791 
   792     typedef std::vector<std::pair<SectionReader*, bool> > SectionReaders;
   793     SectionReaders readers;
   794 
   795   };
   796 
   797   /// \ingroup section_io
   798   /// \brief SectionReader for reading a graph's nodeset.
   799   ///
   800   /// The lemon format can store multiple graph nodesets with several
   801   /// maps.  The nodeset section's header line is \c \@nodeset \c
   802   /// nodeset_name, but the \c nodeset_name may be empty.
   803   ///
   804   /// The first line of the section contains the names of the maps separated
   805   /// with white spaces. Each next lines describes a node in the nodeset, and
   806   /// contains the mapped values for each map.
   807   ///
   808   /// If the nodeset contains an \c "label" named map then it will be regarded
   809   /// as id map. This map should contain only unique values and when the 
   810   /// \c readLabel() member will read a value from the given stream it will
   811   /// give back that node which is mapped to this value.
   812   ///
   813   /// \relates LemonReader
   814   template <typename _Graph, typename _Traits = DefaultReaderTraits>
   815   class NodeSetReader : public LemonReader::SectionReader {
   816     typedef LemonReader::SectionReader Parent;
   817   public:
   818 
   819     typedef _Graph Graph;
   820     typedef _Traits Traits;
   821     typedef typename Graph::Node Node;
   822     typedef typename Traits::Skipper DefaultSkipper;
   823 
   824     /// \brief Constructor.
   825     ///
   826     /// Constructor for NodeSetReader. It creates the NodeSetReader and
   827     /// attach it into the given LemonReader. The nodeset reader will
   828     /// add the read nodes to the given Graph. The reader will read
   829     /// the section when the \c section_name and the \c _name are the same. 
   830     NodeSetReader(LemonReader& _reader, 
   831 		  Graph& _graph, 
   832 		  const std::string& _name = std::string(),
   833 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   834       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {} 
   835 
   836 
   837     /// \brief Destructor.
   838     ///
   839     /// Destructor for NodeSetReader.
   840     virtual ~NodeSetReader() {
   841       for (typename MapReaders::iterator it = readers.begin(); 
   842 	   it != readers.end(); ++it) {
   843 	delete it->second;
   844       }
   845     }
   846 
   847   private:
   848     NodeSetReader(const NodeSetReader&);
   849     void operator=(const NodeSetReader&);
   850   
   851   public:
   852 
   853     /// \brief Add a new node map reader command for the reader.
   854     ///
   855     /// Add a new node map reader command for the reader.
   856     template <typename Map>
   857     NodeSetReader& readNodeMap(std::string label, Map& map) {
   858       return _readMap<
   859 	typename Traits::template Reader<typename Map::Value>, Map,
   860 	typename _reader_bits::Arg<Map>::Type>(label, map);
   861     }
   862 
   863     template <typename Map>
   864     NodeSetReader& readNodeMap(std::string label, const Map& map) {
   865       return _readMap<
   866 	typename Traits::template Reader<typename Map::Value>, Map,
   867 	typename _reader_bits::Arg<Map>::Type>(label, map);
   868     }
   869 
   870     /// \brief Add a new node map reader command for the reader.
   871     ///
   872     /// Add a new node map reader command for the reader.
   873     template <typename ItemReader, typename Map>
   874     NodeSetReader& readNodeMap(std::string label, Map& map, 
   875 			       const ItemReader& ir = ItemReader()) {
   876       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
   877 	(label, map, ir);
   878     }
   879 
   880     template <typename ItemReader, typename Map>
   881     NodeSetReader& readNodeMap(std::string label, const Map& map, 
   882 			       const ItemReader& ir = ItemReader()) {
   883       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
   884 	(label, map, ir);
   885     }
   886 
   887   private:
   888 
   889     template <typename ItemReader, typename Map, typename MapParameter>
   890     NodeSetReader& _readMap(std::string label, MapParameter map, 
   891 			    const ItemReader& ir = ItemReader()) {
   892       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
   893       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
   894       if (readers.find(label) != readers.end()) {
   895 	ErrorMessage msg;
   896 	msg << "Multiple read rule for node map: " << label;
   897 	throw IoParameterError(msg.message());
   898       }      
   899       readers.insert(
   900         make_pair(label, new _reader_bits::
   901 		  MapReader<Node, Map, ItemReader>(map, ir)));
   902       return *this;
   903     }
   904 
   905   public:
   906 
   907     /// \brief Add a new node map skipper command for the reader.
   908     ///
   909     /// Add a new node map skipper command for the reader.
   910     template <typename ItemReader>
   911     NodeSetReader& skipNodeMap(std::string label, 
   912                                const ItemReader& ir = ItemReader()) {
   913       if (readers.find(label) != readers.end()) {
   914 	ErrorMessage msg;
   915 	msg << "Multiple read rule for node map: " << label;
   916 	throw IoParameterError(msg.message());
   917       }
   918       readers.insert(make_pair(label, new _reader_bits::
   919 			       SkipReader<Node, ItemReader>(ir)));
   920       return *this;
   921     }
   922 
   923   protected:
   924 
   925     /// \brief Gives back true when the SectionReader can process 
   926     /// the section with the given header line.
   927     ///
   928     /// It gives back true when the header line starts with \c \@nodeset,
   929     /// and the header line's name and the nodeset's name are the same.
   930     virtual bool header(const std::string& line) {
   931       std::istringstream ls(line);
   932       std::string command;
   933       std::string id;
   934       ls >> command >> id;
   935       return command == "@nodeset" && name == id;
   936     }
   937 
   938     /// \brief Reader function of the section.
   939     ///
   940     /// It reads the content of the section.
   941     virtual void read(std::istream& is) {
   942       std::vector<_reader_bits::MapReaderBase<Node>* > index;
   943       std::string line;
   944 
   945       {
   946         getline(is, line);
   947         std::istringstream ls(line);
   948         std::string id;
   949         while (ls >> id) {
   950           typename MapReaders::iterator it = readers.find(id);
   951           if (it != readers.end()) {
   952             it->second->touch();
   953             index.push_back(it->second);
   954           } else {
   955             index.push_back(&skipper);
   956           }
   957           if (id == "label") {
   958             inverter.reset(index.back()->getInverter());
   959             index.back() = inverter.get();
   960           }
   961         }
   962       }
   963       for (typename MapReaders::iterator it = readers.begin();
   964 	   it != readers.end(); ++it) {
   965 	if (!it->second->touched()) {
   966 	  ErrorMessage msg;
   967 	  msg << "Map not found in file: " << it->first;
   968 	  throw IoParameterError(msg.message());
   969 	}
   970       }
   971       while (getline(is, line)) {	
   972 	Node node = graph.addNode();
   973 	std::istringstream ls(line);
   974 	for (int i = 0; i < int(index.size()); ++i) {
   975 	  index[i]->read(ls, node);
   976 	}
   977       }
   978     }
   979 
   980     virtual void missing() {
   981       if (readers.empty()) return;
   982       ErrorMessage msg;
   983       msg << "NodeSet section not found in file: @nodeset " << name;
   984       throw IoParameterError(msg.message());
   985     }
   986 
   987   public:
   988 
   989     /// \brief Returns true if the nodeset can give back the node by its label.
   990     ///
   991     /// Returns true if the nodeset can give back the node by its label.
   992     /// It is possible only if an "label" named map was read.
   993     bool isLabelReader() const {
   994       return inverter.get() != 0;
   995     }
   996 
   997     /// \brief Gives back the node by its label.
   998     ///
   999     /// It reads an id from the stream and gives back which node belongs to
  1000     /// it. It is possible only if there was read an "label" named map.
  1001     void readLabel(std::istream& is, Node& node) const {
  1002       node = inverter->read(is);
  1003     } 
  1004 
  1005   private:
  1006 
  1007     typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
  1008     MapReaders readers;
  1009    
  1010     Graph& graph;   
  1011     std::string name;
  1012     _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
  1013 
  1014     std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
  1015   };
  1016 
  1017   /// \ingroup section_io
  1018   /// \brief SectionReader for reading a bipartite graph's nodeset.
  1019   ///
  1020   /// The lemon format can store multiple bipartite graph nodesets
  1021   /// with several maps. The bipartite graph nodeset section's header
  1022   /// line is \c \@bpnodeset \c bpnodeset_name, but the \c bpnodeset_name
  1023   /// may be empty.
  1024   ///
  1025   /// The first line of the section contains \c "&anodeset" and the
  1026   /// the names of the A-node maps and regular maps separated with
  1027   /// white spaces. Each next lines describes an A-node in the anodeset,
  1028   /// and contains the mapped values for each map. If one of the line
  1029   /// starts with \c "&bnodeset" then this line contains the names of
  1030   /// the B-node maps and the regular node maps. And the remaining lines
  1031   /// contains the mapped values to the B-nodes.
  1032   ///
  1033   /// If there is "label" named map then it should be defined in both
  1034   /// nodeset, and it will be regarded as id map. This map should
  1035   /// contain only unique values and when the \c readLabel() member
  1036   /// will read a value from the given stream it will give back that
  1037   /// node which is mapped to this value.
  1038   ///
  1039   /// \relates LemonReader
  1040   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  1041   class BpNodeSetReader : public LemonReader::SectionReader {
  1042     typedef LemonReader::SectionReader Parent;
  1043   public:
  1044 
  1045     typedef _Graph Graph;
  1046     typedef _Traits Traits;
  1047     typedef typename Graph::Node Node;
  1048     typedef typename Traits::Skipper DefaultSkipper;
  1049 
  1050     /// \brief Constructor.
  1051     ///
  1052     /// Constructor for BpNodeSetReader. It creates the BpNodeSetReader and
  1053     /// attach it into the given LemonReader. The nodeset reader will
  1054     /// add the read nodes to the given Graph. The reader will read
  1055     /// the section when the \c section_name and the \c _name are the same. 
  1056     BpNodeSetReader(LemonReader& _reader, 
  1057 		  Graph& _graph, 
  1058 		  const std::string& _name = std::string(),
  1059 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
  1060       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {} 
  1061 
  1062 
  1063     /// \brief Destructor.
  1064     ///
  1065     /// Destructor for BpNodeSetReader.
  1066     virtual ~BpNodeSetReader() {
  1067       for (typename MapReaders::iterator it = readers.begin(); 
  1068 	   it != readers.end(); ++it) {
  1069 	delete it->second;
  1070       }
  1071     }
  1072 
  1073   private:
  1074     BpNodeSetReader(const BpNodeSetReader&);
  1075     void operator=(const BpNodeSetReader&);
  1076   
  1077   public:
  1078 
  1079     /// \brief Add a new node map reader command for the reader.
  1080     ///
  1081     /// Add a new node map reader command for the reader.
  1082     template <typename Map>
  1083     BpNodeSetReader& readNodeMap(std::string label, Map& map) {
  1084       return _readMap<
  1085 	typename Traits::template Reader<typename Map::Value>, Map,
  1086 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1087     }
  1088 
  1089     template <typename Map>
  1090     BpNodeSetReader& readNodeMap(std::string label, const Map& map) {
  1091       return _readMap<
  1092 	typename Traits::template Reader<typename Map::Value>, Map,
  1093 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1094     }
  1095 
  1096     /// \brief Add a new node map reader command for the reader.
  1097     ///
  1098     /// Add a new node map reader command for the reader.
  1099     template <typename ItemReader, typename Map>
  1100     BpNodeSetReader& readNodeMap(std::string label, Map& map, 
  1101 			       const ItemReader& ir = ItemReader()) {
  1102       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  1103 	(label, map, ir);
  1104     }
  1105 
  1106     template <typename ItemReader, typename Map>
  1107     BpNodeSetReader& readNodeMap(std::string label, const Map& map, 
  1108 			       const ItemReader& ir = ItemReader()) {
  1109       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  1110 	(label, map, ir);
  1111     }
  1112 
  1113   private:
  1114 
  1115     template <typename ItemReader, typename Map, typename MapParameter>
  1116     BpNodeSetReader& _readMap(std::string label, MapParameter map, 
  1117 			    const ItemReader& ir = ItemReader()) {
  1118       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
  1119       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  1120       if (areaders.find(label) != areaders.end() ||
  1121 	  breaders.find(label) != breaders.end() ||
  1122 	  readers.find(label) != readers.end()) {
  1123 	ErrorMessage msg;
  1124 	msg << "Multiple read rule for node map: " << label;
  1125 	throw IoParameterError(msg.message());
  1126       }      
  1127       readers.insert(make_pair(label, new _reader_bits::
  1128 		  MapReader<Node, Map, ItemReader>(map, ir)));
  1129       return *this;
  1130     }
  1131 
  1132   public:
  1133 
  1134     /// \brief Add a new A-node map reader command for the reader.
  1135     ///
  1136     /// Add a new A-node map reader command for the reader.
  1137     template <typename Map>
  1138     BpNodeSetReader& readANodeMap(std::string label, Map& map) {
  1139       return _readAMap<
  1140 	typename Traits::template Reader<typename Map::Value>, Map,
  1141 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1142     }
  1143 
  1144     template <typename Map>
  1145     BpNodeSetReader& readANodeMap(std::string label, const Map& map) {
  1146       return _readAMap<
  1147 	typename Traits::template Reader<typename Map::Value>, Map,
  1148 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1149     }
  1150 
  1151     /// \brief Add a new A-node map reader command for the reader.
  1152     ///
  1153     /// Add a new A-node map reader command for the reader.
  1154     template <typename ItemReader, typename Map>
  1155     BpNodeSetReader& readANodeMap(std::string label, Map& map, 
  1156 			       const ItemReader& ir = ItemReader()) {
  1157       return _readAMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  1158 	(label, map, ir);
  1159     }
  1160 
  1161     template <typename ItemReader, typename Map>
  1162     BpNodeSetReader& readANodeMap(std::string label, const Map& map, 
  1163 			       const ItemReader& ir = ItemReader()) {
  1164       return _readAMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  1165 	(label, map, ir);
  1166     }
  1167 
  1168   private:
  1169 
  1170     template <typename ItemReader, typename Map, typename MapParameter>
  1171     BpNodeSetReader& _readAMap(std::string label, MapParameter map, 
  1172 			    const ItemReader& ir = ItemReader()) {
  1173       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
  1174       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  1175       if (label == "label") {
  1176 	throw IoParameterError("Label cannot be A-node map");
  1177       }
  1178       if (areaders.find(label) != areaders.end() ||
  1179 	  readers.find(label) != readers.end()) {
  1180 	ErrorMessage msg;
  1181 	msg << "Multiple read rule for A-node map: " << label;
  1182 	throw IoParameterError(msg.message());
  1183       }
  1184       areaders.insert(make_pair(label, new _reader_bits::
  1185 				MapReader<Node, Map, ItemReader>(map, ir)));
  1186       return *this;
  1187     }
  1188 
  1189   public:
  1190 
  1191     /// \brief Add a new B-node map reader command for the reader.
  1192     ///
  1193     /// Add a new B-node map reader command for the reader.
  1194     template <typename Map>
  1195     BpNodeSetReader& readBNodeMap(std::string label, Map& map) {
  1196       return _readBMap<
  1197 	typename Traits::template Reader<typename Map::Value>, Map,
  1198 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1199     }
  1200 
  1201     template <typename Map>
  1202     BpNodeSetReader& readBNodeMap(std::string label, const Map& map) {
  1203       return _readBMap<
  1204 	typename Traits::template Reader<typename Map::Value>, Map,
  1205 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1206     }
  1207 
  1208     /// \brief Add a new B-node map reader command for the reader.
  1209     ///
  1210     /// Add a new B-node map reader command for the reader.
  1211     template <typename ItemReader, typename Map>
  1212     BpNodeSetReader& readBNodeMap(std::string label, Map& map, 
  1213 			       const ItemReader& ir = ItemReader()) {
  1214       return _readBMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  1215 	(label, map, ir);
  1216     }
  1217 
  1218     template <typename ItemReader, typename Map>
  1219     BpNodeSetReader& readBNodeMap(std::string label, const Map& map, 
  1220 			       const ItemReader& ir = ItemReader()) {
  1221       return _readBMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  1222 	(label, map, ir);
  1223     }
  1224 
  1225   private:
  1226 
  1227     template <typename ItemReader, typename Map, typename MapParameter>
  1228     BpNodeSetReader& _readBMap(std::string label, MapParameter map, 
  1229 			    const ItemReader& ir = ItemReader()) {
  1230       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
  1231       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  1232       if (label == "label") {
  1233 	throw IoParameterError("Label cannot be B-node map");
  1234       }
  1235       if (breaders.find(label) != breaders.end() ||
  1236 	  readers.find(label) != readers.end()) {
  1237 	ErrorMessage msg;
  1238 	msg << "Multiple read rule for B-node map: " << label;
  1239 	throw IoParameterError(msg.message());
  1240       }
  1241       breaders.insert(make_pair(label, new _reader_bits::
  1242 				MapReader<Node, Map, ItemReader>(map, ir)));
  1243       return *this;
  1244     }
  1245 
  1246   public:
  1247 
  1248     /// \brief Add a new node map skipper command for the reader.
  1249     ///
  1250     /// Add a new node map skipper command for the reader.
  1251     template <typename ItemReader>
  1252     BpNodeSetReader& skipNodeMap(std::string label, 
  1253 				 const ItemReader& ir = ItemReader()) {
  1254       if (areaders.find(label) != areaders.end() ||
  1255 	  breaders.find(label) != breaders.end() ||
  1256 	  readers.find(label) != readers.end()) {
  1257 	ErrorMessage msg;
  1258 	msg << "Multiple read rule for node map: " << label;
  1259 	throw IoParameterError(msg.message());
  1260       }
  1261       readers.insert(make_pair(label, new _reader_bits::
  1262 			       SkipReader<Node, ItemReader>(ir)));
  1263       return *this;
  1264     }
  1265 
  1266     /// \brief Add a new A-node map skipper command for the reader.
  1267     ///
  1268     /// Add a new A-node map skipper command for the reader.
  1269     template <typename ItemReader>
  1270     BpNodeSetReader& skipANodeMap(std::string label, 
  1271 				  const ItemReader& ir = ItemReader()) {
  1272       if (label == "label") {
  1273 	throw IoParameterError("Label cannot be A-node map");
  1274       }
  1275       if (areaders.find(label) != areaders.end() ||
  1276 	  readers.find(label) != readers.end()) {
  1277 	ErrorMessage msg;
  1278 	msg << "Multiple read rule for A-node map: " << label;
  1279 	throw IoParameterError(msg.message());
  1280       }
  1281       areaders.insert(make_pair(label, new _reader_bits::
  1282 				SkipReader<Node, ItemReader>(ir)));
  1283       return *this;
  1284     }
  1285 
  1286     /// \brief Add a new B-node map skipper command for the reader.
  1287     ///
  1288     /// Add a new B-node map skipper command for the reader.
  1289     template <typename ItemReader>
  1290     BpNodeSetReader& skipBNodeMap(std::string label, 
  1291 				  const ItemReader& ir = ItemReader()) {
  1292       if (label == "label") {
  1293 	throw IoParameterError("Label cannot be B-node map");
  1294       }
  1295       if (breaders.find(label) != breaders.end() ||
  1296 	  readers.find(label) != readers.end()) {
  1297 	ErrorMessage msg;
  1298 	msg << "Multiple read rule for B-node map: " << label;
  1299 	throw IoParameterError(msg.message());
  1300       }
  1301       breaders.insert(make_pair(label, new _reader_bits::
  1302 				SkipReader<Node, ItemReader>(ir)));
  1303       return *this;
  1304     }
  1305 
  1306 
  1307   protected:
  1308 
  1309     /// \brief Gives back true when the SectionReader can process 
  1310     /// the section with the given header line.
  1311     ///
  1312     /// It gives back true when the header line starts with \c \@nodeset,
  1313     /// and the header line's name and the nodeset's name are the same.
  1314     virtual bool header(const std::string& line) {
  1315       std::istringstream ls(line);
  1316       std::string command;
  1317       std::string id;
  1318       ls >> command >> id;
  1319       return command == "@bpnodeset" && name == id;
  1320     }
  1321 
  1322     /// \brief Reader function of the section.
  1323     ///
  1324     /// It reads the content of the section.
  1325     virtual void read(std::istream& is) {
  1326       std::string line;
  1327       {
  1328 	std::vector<_reader_bits::MapReaderBase<Node>* > index;
  1329 	{
  1330 	  getline(is, line);
  1331 	  std::istringstream ls(line);
  1332 	  std::string id;
  1333 	  ls >> id;
  1334 	  if (id != "&anodeset") {
  1335 	    throw IoParameterError("Cannot find &anodeset subsection");
  1336 	  }
  1337 	  while (ls >> id) {
  1338 	    typename MapReaders::iterator it = readers.find(id);
  1339 	    typename MapReaders::iterator ait = areaders.find(id);
  1340 	    if (it != readers.end()) {
  1341 	      it->second->touch();
  1342 	      index.push_back(it->second);
  1343 	    } else if (ait != areaders.end()) {
  1344 	      ait->second->touch();
  1345 	      index.push_back(ait->second);
  1346 	    }
  1347 	    if (id == "label") {
  1348 	      inverter.reset(index.back()->getInverter());
  1349 	      index.back() = inverter.get();
  1350 	    }
  1351 	  }
  1352 	}
  1353 	for (typename MapReaders::iterator it = areaders.begin();
  1354 	     it != areaders.end(); ++it) {
  1355 	  if (!it->second->touched()) {
  1356 	    ErrorMessage msg;
  1357 	    msg << "Map not found in file: " << it->first;
  1358 	    throw IoParameterError(msg.message());
  1359 	  }
  1360 	}
  1361 	for (typename MapReaders::iterator it = readers.begin();
  1362 	     it != readers.end(); ++it) {
  1363 	  if (!it->second->touched()) {
  1364 	    ErrorMessage msg;
  1365 	    msg << "Map not found in file: " << it->first;
  1366 	    throw IoParameterError(msg.message());
  1367 	  }
  1368 	  it->second->touch(false);
  1369 	}
  1370 
  1371 	while (getline(is, line)) {
  1372 	  if (line[0] == '&') {
  1373 	    std::istringstream ls(line);
  1374 	    std::string id;
  1375 	    ls >> id;
  1376 	    if (id == "&bnodeset") break;
  1377 	  }
  1378 	  Node node = graph.addANode();
  1379 	  std::istringstream ls(line);
  1380 	  for (int i = 0; i < int(index.size()); ++i) {
  1381 	    index[i]->read(ls, node);
  1382 	  }
  1383 	}
  1384       }
  1385 
  1386       {
  1387 	std::vector<_reader_bits::MapReaderBase<Node>* > index;
  1388 	{
  1389 	  std::istringstream ls(line);
  1390 	  std::string id;
  1391 	  ls >> id;
  1392 	  if (id != "&bnodeset") {
  1393 	    throw IoParameterError("Cannot find &bnodeset subsection");
  1394 	  }
  1395 	  while (ls >> id) {
  1396 	    typename MapReaders::iterator it = readers.find(id);
  1397 	    typename MapReaders::iterator bit = breaders.find(id);
  1398 	    if (it != readers.end()) {
  1399 	      it->second->touch();
  1400 	      index.push_back(it->second);
  1401 	    } else if (bit != breaders.end()) {
  1402 	      bit->second->touch();
  1403 	      index.push_back(bit->second);
  1404 	    }
  1405 	    if (id == "label" && inverter.get() != 0) {
  1406 	      index.back() = inverter.get();
  1407 	    }
  1408 	  }
  1409 	}
  1410 	for (typename MapReaders::iterator it = breaders.begin();
  1411 	     it != breaders.end(); ++it) {
  1412 	  if (!it->second->touched()) {
  1413 	    ErrorMessage msg;
  1414 	    msg << "Map not found in file: " << it->first;
  1415 	    throw IoParameterError(msg.message());
  1416 	  }
  1417 	}
  1418 	for (typename MapReaders::iterator it = readers.begin();
  1419 	     it != readers.end(); ++it) {
  1420 	  if (!it->second->touched()) {
  1421 	    ErrorMessage msg;
  1422 	    msg << "Map not found in file: " << it->first;
  1423 	    throw IoParameterError(msg.message());
  1424 	  }
  1425 	}
  1426 	while (getline(is, line)) {	
  1427 	  Node node = graph.addBNode();
  1428 	  std::istringstream ls(line);
  1429 	  for (int i = 0; i < int(index.size()); ++i) {
  1430 	    index[i]->read(ls, node);
  1431 	  }
  1432 	}
  1433       }
  1434     }
  1435 
  1436     virtual void missing() {
  1437       if (readers.empty()) return;
  1438       ErrorMessage msg;
  1439       msg << "BpNodeSet section not found in file: @bpnodeset " << name;
  1440       throw IoParameterError(msg.message());
  1441     }
  1442 
  1443   public:
  1444 
  1445     /// \brief Returns true if the nodeset can give back the node by its label.
  1446     ///
  1447     /// Returns true if the nodeset can give back the node by its label.
  1448     /// It is possible only if an "label" named map was read.
  1449     bool isLabelReader() const {
  1450       return inverter.get() != 0;
  1451     }
  1452 
  1453     /// \brief Gives back the node by its label.
  1454     ///
  1455     /// It reads an id from the stream and gives back which node belongs to
  1456     /// it. It is possible only if there was read an "label" named map.
  1457     void readLabel(std::istream& is, Node& node) const {
  1458       node = inverter->read(is);
  1459     } 
  1460 
  1461   private:
  1462 
  1463     typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> 
  1464     MapReaders;
  1465     
  1466     MapReaders areaders, breaders, readers;
  1467    
  1468     Graph& graph;
  1469     std::string name;
  1470     _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
  1471 
  1472     std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
  1473   };
  1474 
  1475 
  1476   /// \ingroup section_io
  1477   /// \brief SectionReader for reading a graph's edgeset.
  1478   ///
  1479   /// The lemon format can store multiple graph edgesets with several maps.
  1480   /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but the
  1481   /// \c edgeset_name may be empty.
  1482   ///
  1483   /// The first line of the section contains the names of the maps separated
  1484   /// with white spaces. Each next lines describes an edge in the edgeset. The
  1485   /// line contains the source and the target nodes' id and the mapped 
  1486   /// values for each map.
  1487   ///
  1488   /// If the edgeset contains an \c "label" named map then it will be regarded
  1489   /// as id map. This map should contain only unique values and when the 
  1490   /// \c readLabel() member will read a value from the given stream it will
  1491   /// give back that edge which is mapped to this value.
  1492   ///
  1493   /// The edgeset reader needs a node id reader to identify which nodes
  1494   /// have to be connected. If a NodeSetReader reads an "label" named map,
  1495   /// it will be able to resolve the nodes by ids.
  1496   ///
  1497   /// \relates LemonReader
  1498   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  1499   class EdgeSetReader : public LemonReader::SectionReader {
  1500     typedef LemonReader::SectionReader Parent;
  1501   public:
  1502 
  1503     typedef _Graph Graph;
  1504     typedef _Traits Traits;
  1505     typedef typename Graph::Node Node;
  1506     typedef typename Graph::Edge Edge;
  1507     typedef typename Traits::Skipper DefaultSkipper;
  1508 
  1509     /// \brief Constructor.
  1510     ///
  1511     /// Constructor for EdgeSetReader. It creates the EdgeSetReader and
  1512     /// attach it into the given LemonReader. The edgeset reader will
  1513     /// add the read edges to the given Graph. It will use the given
  1514     /// node id reader to read the source and target nodes of the edges.
  1515     /// The reader will read the section only if the \c _name and the 
  1516     /// \c edgset_name are the same. 
  1517     template <typename NodeLabelReader>
  1518     EdgeSetReader(LemonReader& _reader, 
  1519 		  Graph& _graph, 
  1520 		  const NodeLabelReader& _nodeLabelReader, 
  1521 		  const std::string& _name = std::string(),
  1522 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
  1523       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
  1524       checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
  1525       nodeLabelReader.reset(new _reader_bits::
  1526 			 LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
  1527     }
  1528     /// \brief Destructor.
  1529     ///
  1530     /// Destructor for EdgeSetReader.
  1531     virtual ~EdgeSetReader() {
  1532       for (typename MapReaders::iterator it = readers.begin(); 
  1533 	   it != readers.end(); ++it) {
  1534 	delete it->second;
  1535       }
  1536     }
  1537 
  1538   private:
  1539     EdgeSetReader(const EdgeSetReader&);
  1540     void operator=(const EdgeSetReader&);
  1541 
  1542   public:
  1543 
  1544     /// \brief Add a new edge map reader command for the reader.
  1545     ///
  1546     /// Add a new edge map reader command for the reader.
  1547     template <typename Map>
  1548     EdgeSetReader& readEdgeMap(std::string label, Map& map) {
  1549       return _readMap<
  1550 	typename Traits::template Reader<typename Map::Value>, Map,
  1551 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1552     }
  1553 
  1554     template <typename Map>
  1555     EdgeSetReader& readEdgeMap(std::string label, const Map& map) {
  1556       return _readMap<
  1557 	typename Traits::template Reader<typename Map::Value>, Map,
  1558 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1559     }
  1560 
  1561     /// \brief Add a new edge map reader command for the reader.
  1562     ///
  1563     /// Add a new edge map reader command for the reader.
  1564     template <typename ItemReader, typename Map>
  1565     EdgeSetReader& readEdgeMap(std::string label, Map& map, 
  1566                                const ItemReader& ir = ItemReader()) {
  1567       return _readMap<ItemReader, Map,
  1568 	typename _reader_bits::Arg<Map>::Type>(label, map, ir);
  1569     }
  1570 
  1571     template <typename ItemReader, typename Map>
  1572     EdgeSetReader& readEdgeMap(std::string label, const Map& map, 
  1573 			       const ItemReader& ir = ItemReader()) {
  1574       return _readMap<ItemReader, Map,
  1575 	typename _reader_bits::Arg<Map>::Type>(label, map, ir);
  1576     }
  1577 
  1578   private:
  1579 
  1580     template <typename ItemReader, typename Map, typename MapParameter>
  1581     EdgeSetReader& _readMap(std::string label, MapParameter map, 
  1582 			    const ItemReader& ir = ItemReader()) {
  1583       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
  1584       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  1585       if (readers.find(label) != readers.end()) {
  1586 	ErrorMessage msg;
  1587 	msg << "Multiple read rule for edge map: " << label;
  1588 	throw IoParameterError(msg.message());
  1589       }
  1590       readers.insert(
  1591 	make_pair(label, new _reader_bits::
  1592 		  MapReader<Edge, Map, ItemReader>(map, ir)));
  1593       return *this;
  1594     }
  1595 
  1596   public:
  1597 
  1598     /// \brief Add a new edge map skipper command for the reader.
  1599     ///
  1600     /// Add a new edge map skipper command for the reader.
  1601     template <typename ItemReader>
  1602     EdgeSetReader& skipEdgeMap(std::string label, 
  1603 			       const ItemReader& ir = ItemReader()) {
  1604       if (readers.find(label) != readers.end()) {
  1605 	ErrorMessage msg;
  1606 	msg << "Multiple read rule for edge map: " << label;
  1607 	throw IoParameterError(msg.message());
  1608       }
  1609       readers.insert(make_pair(label, new _reader_bits::
  1610 			       SkipReader<Edge, ItemReader>(ir)));
  1611       return *this;
  1612     }
  1613 
  1614   protected:
  1615 
  1616     /// \brief Gives back true when the SectionReader can process 
  1617     /// the section with the given header line.
  1618     ///
  1619     /// It gives back true when the header line starts with \c \@edgeset,
  1620     /// and the header line's name and the edgeset's name are the same.
  1621     /// The sections with \@uedgeset head line could be read with this
  1622     /// section reader too.
  1623     virtual bool header(const std::string& line) {
  1624       std::istringstream ls(line);
  1625       std::string command;
  1626       std::string id;
  1627       ls >> command >> id;
  1628       return (command == "@edgeset" || command == "@uedgeset") && name == id;
  1629     }
  1630 
  1631     /// \brief Reader function of the section.
  1632     ///
  1633     /// It reads the content of the section.
  1634     virtual void read(std::istream& is) {
  1635       if (!nodeLabelReader->isLabelReader()) {
  1636 	throw DataFormatError("Cannot find nodeset or label map");
  1637       }
  1638       std::vector<_reader_bits::MapReaderBase<Edge>* > index;
  1639       std::string line;
  1640 
  1641       {
  1642         getline(is, line);
  1643         std::istringstream ls(line);	
  1644         std::string id;
  1645         while (ls >> id) {
  1646           typename MapReaders::iterator it = readers.find(id);
  1647           if (it != readers.end()) {
  1648             index.push_back(it->second);
  1649             it->second->touch();
  1650           } else {
  1651             index.push_back(&skipper);
  1652           }
  1653           if (id == "label") {
  1654             inverter.reset(index.back()->getInverter());
  1655             index.back() = inverter.get();
  1656           }
  1657         }
  1658       }
  1659       for (typename MapReaders::iterator it = readers.begin();
  1660 	   it != readers.end(); ++it) {
  1661 	if (!it->second->touched()) {
  1662 	  ErrorMessage msg;
  1663 	  msg << "Map not found in file: " << it->first;
  1664 	  throw IoParameterError(msg.message());
  1665 	}
  1666       }
  1667       while (getline(is, line)) {	
  1668 	std::istringstream ls(line);
  1669 	Node from = nodeLabelReader->read(ls);
  1670 	Node to = nodeLabelReader->read(ls);
  1671 	Edge edge = graph.addEdge(from, to);
  1672 	for (int i = 0; i < int(index.size()); ++i) {
  1673 	  index[i]->read(ls, edge);
  1674 	}
  1675       }
  1676     }
  1677 
  1678     virtual void missing() {
  1679       if (readers.empty()) return;
  1680       ErrorMessage msg;
  1681       msg << "EdgeSet section not found in file: @edgeset " << name;
  1682       throw IoParameterError(msg.message());
  1683     }
  1684 
  1685   public:
  1686 
  1687     /// \brief Returns true if the edgeset can give back the edge by its label.
  1688     ///
  1689     /// Returns true if the edgeset can give back the edge by its label.
  1690     /// It is possible only if an "label" named map was read.
  1691     bool isLabelReader() const {
  1692       return inverter.get() != 0;
  1693     }
  1694 
  1695     /// \brief Gives back the edge by its label.
  1696     ///
  1697     /// It reads an id from the stream and gives back which edge belongs to
  1698     /// it. It is possible only if there was read an "label" named map.
  1699     void readLabel(std::istream& is, Edge& edge) const {
  1700       edge = inverter->read(is);
  1701     } 
  1702 
  1703   private:
  1704 
  1705     typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> 
  1706     MapReaders;
  1707     
  1708     MapReaders readers;
  1709    
  1710     Graph& graph;   
  1711     std::string name;
  1712     _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
  1713 
  1714     std::auto_ptr<_reader_bits::MapInverterBase<Edge> > inverter;
  1715     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
  1716   };
  1717 
  1718   /// \ingroup section_io
  1719   /// \brief SectionReader for reading a undirected graph's edgeset.
  1720   ///
  1721   /// The lemon format can store multiple undirected edgesets with several 
  1722   /// maps. The undirected edgeset section's header line is \c \@uedgeset 
  1723   /// \c uedgeset_name, but the \c uedgeset_name may be empty.
  1724   ///
  1725   /// The first line of the section contains the names of the maps separated
  1726   /// with white spaces. Each next lines describes an edge in the edgeset. The
  1727   /// line contains the connected nodes' id and the mapped values for each map.
  1728   ///
  1729   /// The section can handle the directed as a syntactical sugar. Two
  1730   /// undirected edge map describes one directed edge map. This two maps
  1731   /// are the forward map and the backward map and the names of this map
  1732   /// is near the same just with a prefix \c '+' or \c '-' character 
  1733   /// difference.
  1734   ///
  1735   /// If the edgeset contains an \c "label" named map then it will be regarded
  1736   /// as id map. This map should contain only unique values and when the 
  1737   /// \c readLabel() member will read a value from the given stream it will
  1738   /// give back that uicted edge which is mapped to this value.
  1739   ///
  1740   /// The undirected edgeset reader needs a node id reader to identify which 
  1741   /// nodes have to be connected. If a NodeSetReader reads an "label" named 
  1742   /// map, it will be able to resolve the nodes by ids.
  1743   ///
  1744   /// \relates LemonReader
  1745   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  1746   class UEdgeSetReader : public LemonReader::SectionReader {
  1747     typedef LemonReader::SectionReader Parent;
  1748   public:
  1749 
  1750     typedef _Graph Graph;
  1751     typedef _Traits Traits;
  1752     typedef typename Graph::Node Node;
  1753     typedef typename Graph::Edge Edge;
  1754     typedef typename Graph::UEdge UEdge;
  1755     typedef typename Traits::Skipper DefaultSkipper;
  1756 
  1757     /// \brief Constructor.
  1758     ///
  1759     /// Constructor for UEdgeSetReader. It creates the UEdgeSetReader 
  1760     /// and attach it into the given LemonReader. The undirected edgeset 
  1761     /// reader will add the read undirected edges to the given Graph. It 
  1762     /// will use the given node id reader to read the source and target 
  1763     /// nodes of the edges. The reader will read the section only if the 
  1764     /// \c _name and the \c uedgset_name are the same. 
  1765     template <typename NodeLabelReader>
  1766     UEdgeSetReader(LemonReader& _reader, 
  1767 		       Graph& _graph, 
  1768 		       const NodeLabelReader& _nodeLabelReader, 
  1769 		       const std::string& _name = std::string(),
  1770 		       const DefaultSkipper& _skipper = DefaultSkipper()) 
  1771       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
  1772       checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
  1773       nodeLabelReader.reset(new _reader_bits::
  1774 			 LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
  1775     }
  1776     /// \brief Destructor.
  1777     ///
  1778     /// Destructor for UEdgeSetReader.
  1779     virtual ~UEdgeSetReader() {
  1780       for (typename MapReaders::iterator it = readers.begin(); 
  1781 	   it != readers.end(); ++it) {
  1782 	delete it->second;
  1783       }
  1784     }
  1785 
  1786   private:
  1787     UEdgeSetReader(const UEdgeSetReader&);
  1788     void operator=(const UEdgeSetReader&);
  1789 
  1790   public:
  1791 
  1792     /// \brief Add a new undirected edge map reader command for the reader.
  1793     ///
  1794     /// Add a new edge undirected map reader command for the reader.
  1795     template <typename Map>
  1796     UEdgeSetReader& readUEdgeMap(std::string label, Map& map) {
  1797       return _readMap<
  1798 	typename Traits::template Reader<typename Map::Value>, Map, 
  1799 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1800     }
  1801 
  1802     template <typename Map>
  1803     UEdgeSetReader& readUEdgeMap(std::string label, const Map& map) {
  1804       return _readMap<
  1805 	typename Traits::template Reader<typename Map::Value>, Map, 
  1806 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1807     }
  1808 
  1809     /// \brief Add a new undirected edge map reader command for the reader.
  1810     ///
  1811     /// Add a new edge undirected map reader command for the reader.
  1812     template <typename ItemReader, typename Map>
  1813     UEdgeSetReader& readUEdgeMap(std::string label, Map& map, 
  1814                                  const ItemReader& ir = ItemReader()) {
  1815       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  1816 	(label, map, ir);
  1817     }
  1818 
  1819     template <typename ItemReader, typename Map>
  1820     UEdgeSetReader& readUEdgeMap(std::string label, const Map& map, 
  1821                                  const ItemReader& ir = ItemReader()) {
  1822       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type >
  1823 	(label, map, ir);
  1824     }
  1825 
  1826   private:
  1827 
  1828     template <typename ItemReader, typename Map, typename MapParameter>
  1829     UEdgeSetReader& _readMap(std::string label, MapParameter map,
  1830                              const ItemReader& ir = ItemReader()) {
  1831       checkConcept<concepts::WriteMap<UEdge, typename Map::Value>, Map>();
  1832       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  1833       if (readers.find(label) != readers.end()) {
  1834 	ErrorMessage msg;
  1835 	msg << "Multiple read rule for edge map: " << label;
  1836 	throw IoParameterError(msg.message());
  1837       }
  1838       readers.insert(
  1839 	make_pair(label, new _reader_bits::
  1840 		  MapReader<UEdge, Map, ItemReader>(map, ir)));
  1841       return *this;
  1842     }
  1843 
  1844   public:
  1845 
  1846     /// \brief Add a new undirected edge map skipper command for the reader.
  1847     ///
  1848     /// Add a new undirected edge map skipper command for the reader.
  1849     template <typename ItemReader>
  1850     UEdgeSetReader& skipUEdgeMap(std::string label, 
  1851                                  const ItemReader& ir = ItemReader()) {
  1852       if (readers.find(label) != readers.end()) {
  1853 	ErrorMessage msg;
  1854 	msg << "Multiple read rule for node map: " << label;
  1855 	throw IoParameterError(msg.message());
  1856       }
  1857       readers.insert(make_pair(label, new _reader_bits::
  1858 			       SkipReader<UEdge, ItemReader>(ir)));
  1859       return *this;
  1860     }
  1861 
  1862     /// \brief Add a new directed edge map reader command for the reader.
  1863     ///
  1864     /// Add a new directed edge map reader command for the reader.
  1865     template <typename Map>
  1866     UEdgeSetReader& readEdgeMap(std::string label, Map& map) {
  1867       return _readDirMap<
  1868 	typename Traits::template Reader<typename Map::Value>, Map,
  1869 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1870     }
  1871 
  1872     template <typename Map>
  1873     UEdgeSetReader& readEdgeMap(std::string label, const Map& map) {
  1874       return _readDirMap<
  1875 	typename Traits::template Reader<typename Map::Value>, Map,
  1876 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1877     }
  1878 
  1879     /// \brief Add a new directed edge map reader command for the reader.
  1880     ///
  1881     /// Add a new directed edge map reader command for the reader.
  1882     template <typename ItemReader, typename Map>
  1883     UEdgeSetReader& readEdgeMap(std::string label, Map& map, 
  1884 				    const ItemReader& ir = ItemReader()) {
  1885       return _readDirMap<ItemReader, Map, 
  1886         typename _reader_bits::Arg<Map>::Type>(label, map, ir);
  1887     }
  1888 
  1889     template <typename ItemReader, typename Map>
  1890     UEdgeSetReader& readEdgeMap(std::string label, const Map& map, 
  1891 				    const ItemReader& ir = ItemReader()) {
  1892       return _readDirMap<ItemReader, Map, 
  1893         typename _reader_bits::Arg<Map>::Type>(label, map, ir);
  1894     }
  1895 
  1896   private:
  1897 
  1898     template <typename ItemReader, typename Map, typename MapParameter>
  1899     UEdgeSetReader& _readDirMap(std::string label, MapParameter map,
  1900 				    const ItemReader& ir = ItemReader()) { 
  1901       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  1902       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
  1903       readUEdgeMap("+" + label, 
  1904                    _reader_bits::forwardComposeMap(graph, map), ir);
  1905       readUEdgeMap("-" + label, 
  1906                    _reader_bits::backwardComposeMap(graph, map), ir);
  1907       return *this;      
  1908     }
  1909 
  1910   public:
  1911 
  1912     /// \brief Add a new directed edge map skipper command for the reader.
  1913     ///
  1914     /// Add a new directed edge map skipper command for the reader.
  1915     template <typename ItemReader>
  1916     UEdgeSetReader& skipEdgeMap(std::string label, 
  1917                                 const ItemReader& ir = ItemReader()) {
  1918       skipUEdgeMap("+" + label, ir);
  1919       skipUEdgeMap("-" + label, ir);
  1920       return *this;
  1921     }
  1922 
  1923   protected:
  1924 
  1925     /// \brief Gives back true when the SectionReader can process 
  1926     /// the section with the given header line.
  1927     ///
  1928     /// It gives back true when the header line starts with \c \@uedgeset,
  1929     /// and the header line's name and the edgeset's name are the same.
  1930     /// The sections with \@edgeset head line could be read with this
  1931     /// section reader too.
  1932     virtual bool header(const std::string& line) {
  1933       std::istringstream ls(line);
  1934       std::string command;
  1935       std::string id;
  1936       ls >> command >> id;
  1937       return (command == "@edgeset" || command == "@uedgeset") && name == id;
  1938     }
  1939 
  1940     /// \brief Reader function of the section.
  1941     ///
  1942     /// It reads the content of the section.
  1943     virtual void read(std::istream& is) {
  1944       if (!nodeLabelReader->isLabelReader()) {
  1945 	throw DataFormatError("Cannot find nodeset or label map");
  1946       }
  1947       std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
  1948       std::string line;
  1949 
  1950       {
  1951         getline(is, line);
  1952         std::istringstream ls(line);	
  1953         std::string id;
  1954         while (ls >> id) {
  1955           typename MapReaders::iterator it = readers.find(id);
  1956           if (it != readers.end()) {
  1957             index.push_back(it->second);
  1958             it->second->touch();
  1959           } else {
  1960             index.push_back(&skipper);
  1961           }
  1962           if (id == "label") {
  1963             inverter.reset(index.back()->getInverter());
  1964             index.back() = inverter.get();
  1965           }
  1966         }
  1967         for (typename MapReaders::iterator it = readers.begin();
  1968              it != readers.end(); ++it) {
  1969           if (!it->second->touched()) {
  1970             ErrorMessage msg;
  1971             msg << "Map not found in file: " << it->first;
  1972             throw IoParameterError(msg.message());
  1973           }
  1974         }
  1975       }
  1976       while (getline(is, line)) {	
  1977 	std::istringstream ls(line);
  1978 	Node from = nodeLabelReader->read(ls);
  1979 	Node to = nodeLabelReader->read(ls);
  1980 	UEdge edge = graph.addEdge(from, to);
  1981 	for (int i = 0; i < int(index.size()); ++i) {
  1982 	  index[i]->read(ls, edge);
  1983 	}
  1984       }
  1985     }
  1986 
  1987     virtual void missing() {
  1988       if (readers.empty()) return;
  1989       ErrorMessage msg;
  1990       msg << "UEdgeSet section not found in file: @uedgeset " << name;
  1991       throw IoParameterError(msg.message());
  1992     }
  1993 
  1994   public:
  1995 
  1996     /// \brief Returns true if the edgeset can give back the edge by its label.
  1997     ///
  1998     /// Returns true if the edgeset can give back the undirected edge by its 
  1999     /// id. It is possible only if an "label" named map was read.
  2000     bool isLabelReader() const {
  2001       return inverter.get() != 0;
  2002     }
  2003 
  2004     /// \brief Gives back the undirected edge by its label.
  2005     ///
  2006     /// It reads an id from the stream and gives back which undirected edge 
  2007     /// belongs to it. It is possible only if there was read an "label" named map.
  2008     void readLabel(std::istream& is, UEdge& uedge) const {
  2009       uedge = inverter->read(is);
  2010     } 
  2011 
  2012     /// \brief Gives back the directed edge by its label.
  2013     ///
  2014     /// It reads an id from the stream and gives back which directed edge 
  2015     /// belongs to it. The directed edge id is the \c '+' or \c '-' character
  2016     /// and the undirected edge id. It is possible only if there was read 
  2017     /// an "label" named map.
  2018     void readLabel(std::istream& is, Edge& edge) const {
  2019       char c;
  2020       is >> c;
  2021       UEdge uedge = inverter->read(is);
  2022       if (c == '+') {
  2023 	edge = graph.direct(uedge, true);
  2024       } else if (c == '-') {
  2025         edge = graph.direct(uedge, false);
  2026       } else {
  2027 	throw DataFormatError("Wrong id format for edge "
  2028 			      "in undirected edgeset");
  2029       }
  2030     } 
  2031 
  2032   private:
  2033 
  2034     typedef std::map<std::string, 
  2035 		     _reader_bits::MapReaderBase<UEdge>*> MapReaders;
  2036     MapReaders readers;
  2037    
  2038     Graph& graph;   
  2039     std::string name;
  2040     _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
  2041 
  2042     std::auto_ptr<_reader_bits::MapInverterBase<UEdge> > inverter;
  2043     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
  2044   };
  2045 
  2046   /// \ingroup section_io
  2047   /// \brief SectionReader for reading labeled nodes.
  2048   ///
  2049   /// The nodes section's header line is \c \@nodes \c nodes_name, but the
  2050   /// \c nodes_name may be empty.
  2051   ///
  2052   /// Each line in the section contains the name of the node 
  2053   /// and then the node id. 
  2054   ///
  2055   /// \relates LemonReader
  2056   template <typename _Graph>
  2057   class NodeReader : public LemonReader::SectionReader {
  2058     typedef LemonReader::SectionReader Parent;
  2059     typedef _Graph Graph;
  2060     typedef typename Graph::Node Node;
  2061   public:
  2062     
  2063     /// \brief Constructor.
  2064     ///
  2065     /// Constructor for NodeReader. It creates the NodeReader and
  2066     /// attach it into the given LemonReader. It will use the given
  2067     /// node id reader to give back the nodes. The reader will read the 
  2068     /// section only if the \c _name and the \c nodes_name are the same. 
  2069     template <typename _LabelReader>
  2070     NodeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  2071 	       const std::string& _name = std::string()) 
  2072       : Parent(_reader), name(_name) {
  2073       checkConcept<_reader_bits::ItemLabelReader<Node>, _LabelReader>();
  2074       nodeLabelReader.reset(new _reader_bits::
  2075 			 LabelReader<Node, _LabelReader>(_labelReader));
  2076     }
  2077 
  2078     /// \brief Destructor.
  2079     ///
  2080     /// Destructor for NodeReader.
  2081     virtual ~NodeReader() {}
  2082 
  2083   private:
  2084     NodeReader(const NodeReader&);
  2085     void operator=(const NodeReader&);
  2086 
  2087   public:
  2088 
  2089     /// \brief Add a node reader command for the NodeReader.
  2090     ///
  2091     /// Add a node reader command for the NodeReader.
  2092     void readNode(std::string label, Node& item) {
  2093       if (readers.find(label) != readers.end()) {
  2094 	ErrorMessage msg;
  2095 	msg << "Multiple read rule for node: " << label;
  2096 	throw IoParameterError(msg.message());
  2097       }
  2098       readers.insert(make_pair(label, _reader_bits::ItemStore<Node>(item)));
  2099     }
  2100 
  2101   protected:
  2102 
  2103     /// \brief Gives back true when the SectionReader can process 
  2104     /// the section with the given header line.
  2105     ///
  2106     /// It gives back true when the header line start with \c \@nodes,
  2107     /// and the header line's name and the reader's name are the same.
  2108     virtual bool header(const std::string& line) {
  2109       std::istringstream ls(line);
  2110       std::string command;
  2111       std::string id;
  2112       ls >> command >> id;
  2113       return command == "@nodes" && name == id;
  2114     }
  2115 
  2116     /// \brief Reader function of the section.
  2117     ///
  2118     /// It reads the content of the section.
  2119     virtual void read(std::istream& is) {
  2120       if (!nodeLabelReader->isLabelReader()) {
  2121 	throw DataFormatError("Cannot find nodeset or label map");
  2122       }
  2123       std::string line;
  2124       while (getline(is, line)) {
  2125 	std::istringstream ls(line);
  2126 	std::string id;
  2127 	ls >> id;
  2128 	typename NodeReaders::iterator it = readers.find(id);
  2129 	if (it != readers.end()) {
  2130 	  it->second.read(nodeLabelReader->read(ls));
  2131 	  it->second.touch();
  2132 	}	
  2133       }
  2134       for (typename NodeReaders::iterator it = readers.begin();
  2135 	   it != readers.end(); ++it) {
  2136 	if (!it->second.touched()) {
  2137 	  ErrorMessage msg;
  2138 	  msg << "Node not found in file: " << it->first;
  2139 	  throw IoParameterError(msg.message());
  2140 	}
  2141       }
  2142     }
  2143 
  2144     virtual void missing() {
  2145       if (readers.empty()) return;
  2146       ErrorMessage msg;
  2147       msg << "Nodes section not found in file: @nodes " << name;
  2148       throw IoParameterError(msg.message());
  2149     }
  2150     
  2151   private:
  2152 
  2153     std::string name;
  2154 
  2155     typedef std::map<std::string, _reader_bits::ItemStore<Node> > NodeReaders;
  2156     NodeReaders readers;
  2157     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
  2158   };
  2159 
  2160   /// \ingroup section_io
  2161   /// \brief SectionReader for reading labeled edges.
  2162   ///
  2163   /// The edges section's header line is \c \@edges \c edges_name, but the
  2164   /// \c edges_name may be empty.
  2165   ///
  2166   /// Each line in the section contains the name of the edge 
  2167   /// and then the edge id. 
  2168   ///
  2169   /// \relates LemonReader
  2170   template <typename _Graph>
  2171   class EdgeReader : public LemonReader::SectionReader {
  2172     typedef LemonReader::SectionReader Parent;
  2173     typedef _Graph Graph;
  2174     typedef typename Graph::Edge Edge;
  2175   public:
  2176     
  2177     /// \brief Constructor.
  2178     ///
  2179     /// Constructor for EdgeReader. It creates the EdgeReader and
  2180     /// attach it into the given LemonReader. It will use the given
  2181     /// edge id reader to give back the edges. The reader will read the 
  2182     /// section only if the \c _name and the \c edges_name are the same. 
  2183     template <typename _LabelReader>
  2184     EdgeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  2185 	       const std::string& _name = std::string()) 
  2186       : Parent(_reader), name(_name) {
  2187       checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
  2188       edgeLabelReader.reset(new _reader_bits::
  2189 			 LabelReader<Edge, _LabelReader>(_labelReader));
  2190     }
  2191 
  2192     /// \brief Destructor.
  2193     ///
  2194     /// Destructor for EdgeReader.
  2195     virtual ~EdgeReader() {}
  2196   private:
  2197     EdgeReader(const EdgeReader&);
  2198     void operator=(const EdgeReader&);
  2199 
  2200   public:
  2201 
  2202     /// \brief Add an edge reader command for the EdgeReader.
  2203     ///
  2204     /// Add an edge reader command for the EdgeReader.
  2205     void readEdge(std::string label, Edge& item) {
  2206       if (readers.find(label) != readers.end()) {
  2207 	ErrorMessage msg;
  2208 	msg << "Multiple read rule for edge: " << label;
  2209 	throw IoParameterError(msg.message());
  2210       }
  2211       readers.insert(make_pair(label, _reader_bits::ItemStore<Edge>(item)));
  2212     }
  2213 
  2214   protected:
  2215 
  2216     /// \brief Gives back true when the SectionReader can process 
  2217     /// the section with the given header line.
  2218     ///
  2219     /// It gives back true when the header line start with \c \@edges,
  2220     /// and the header line's name and the reader's name are the same.
  2221     virtual bool header(const std::string& line) {
  2222       std::istringstream ls(line);
  2223       std::string command;
  2224       std::string id;
  2225       ls >> command >> id;
  2226       return command == "@edges" && name == id;
  2227     }
  2228 
  2229     /// \brief Reader function of the section.
  2230     ///
  2231     /// It reads the content of the section.
  2232     virtual void read(std::istream& is) {
  2233       if (!edgeLabelReader->isLabelReader()) {
  2234 	throw DataFormatError("Cannot find edgeset or label map");
  2235       }
  2236       std::string line;
  2237       while (getline(is, line)) {
  2238 	std::istringstream ls(line);
  2239 	std::string id;
  2240 	ls >> id;
  2241 	typename EdgeReaders::iterator it = readers.find(id);
  2242 	if (it != readers.end()) {
  2243 	  it->second.read(edgeLabelReader->read(ls));
  2244 	  it->second.touch();
  2245 	}	
  2246       }
  2247       for (typename EdgeReaders::iterator it = readers.begin();
  2248 	   it != readers.end(); ++it) {
  2249 	if (!it->second.touched()) {
  2250 	  ErrorMessage msg;
  2251 	  msg << "Edge not found in file: " << it->first;
  2252 	  throw IoParameterError(msg.message());
  2253 	}
  2254       }
  2255     }
  2256 
  2257     virtual void missing() {
  2258       if (readers.empty()) return;
  2259       ErrorMessage msg;
  2260       msg << "Edges section not found in file: @edges " << name;
  2261       throw IoParameterError(msg.message());
  2262     }
  2263     
  2264   private:
  2265 
  2266     std::string name;
  2267 
  2268     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  2269     EdgeReaders readers;
  2270     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
  2271   };
  2272 
  2273   /// \ingroup section_io
  2274   /// \brief SectionReader for reading labeled undirected edges.
  2275   ///
  2276   /// The undirected edges section's header line is \c \@uedges 
  2277   /// \c uedges_name, but the \c uedges_name may be empty.
  2278   ///
  2279   /// Each line in the section contains the name of the undirected edge 
  2280   /// and then the undirected edge id. 
  2281   ///
  2282   /// \relates LemonReader
  2283   template <typename _Graph>
  2284   class UEdgeReader : public LemonReader::SectionReader {
  2285     typedef LemonReader::SectionReader Parent;
  2286     typedef _Graph Graph;
  2287     typedef typename Graph::Edge Edge;
  2288     typedef typename Graph::UEdge UEdge;
  2289   public:
  2290     
  2291     /// \brief Constructor.
  2292     ///
  2293     /// Constructor for UEdgeReader. It creates the UEdgeReader and
  2294     /// attach it into the given LemonReader. It will use the given
  2295     /// undirected edge id reader to give back the edges. The reader will 
  2296     /// read the section only if the \c _name and the \c uedges_name are 
  2297     /// the same. 
  2298     template <typename _LabelReader>
  2299     UEdgeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  2300 	       const std::string& _name = std::string()) 
  2301       : Parent(_reader), name(_name) {
  2302       checkConcept<_reader_bits::ItemLabelReader<UEdge>, _LabelReader>();
  2303       checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
  2304       uedgeLabelReader.reset(new _reader_bits::
  2305 			     LabelReader<UEdge, _LabelReader>(_labelReader));
  2306       edgeLabelReader.reset(new _reader_bits::
  2307 			    LabelReader<Edge, _LabelReader>(_labelReader));
  2308     }
  2309 
  2310     /// \brief Destructor.
  2311     ///
  2312     /// Destructor for UEdgeReader.
  2313     virtual ~UEdgeReader() {}
  2314   private:
  2315     UEdgeReader(const UEdgeReader&);
  2316     void operator=(const UEdgeReader&);
  2317 
  2318   public:
  2319 
  2320     /// \brief Add an undirected edge reader command for the UEdgeReader.
  2321     ///
  2322     /// Add an undirected edge reader command for the UEdgeReader.
  2323     void readUEdge(std::string label, UEdge& item) {
  2324       if (uedgeReaders.find(label) != uedgeReaders.end()) {
  2325 	ErrorMessage msg;
  2326 	msg << "Multiple read rule for undirected edge: " << label;
  2327 	throw IoParameterError(msg.message());
  2328       }
  2329       uedgeReaders.insert(make_pair(label, _reader_bits::
  2330 					ItemStore<UEdge>(item)));
  2331     }
  2332 
  2333     /// \brief Add an edge reader command for the UEdgeReader.
  2334     ///
  2335     /// Add an edge reader command for the UEdgeReader.
  2336     void readEdge(std::string label, Edge& item) {
  2337       if (edgeReaders.find(label) != edgeReaders.end()) {
  2338 	ErrorMessage msg;
  2339 	msg << "Multiple read rule for edge: " << label;
  2340 	throw IoParameterError(msg.message());
  2341       }
  2342       edgeReaders.insert(make_pair(label, _reader_bits::ItemStore<Edge>(item)));
  2343     }
  2344 
  2345   protected:
  2346 
  2347     /// \brief Gives back true when the SectionReader can process 
  2348     /// the section with the given header line.
  2349     ///
  2350     /// It gives back true when the header line start with \c \@edges,
  2351     /// and the header line's name and the reader's name are the same.
  2352     virtual bool header(const std::string& line) {
  2353       std::istringstream ls(line);
  2354       std::string command;
  2355       std::string id;
  2356       ls >> command >> id;
  2357       return command == "@uedges" && name == id;
  2358     }
  2359 
  2360     /// \brief Reader function of the section.
  2361     ///
  2362     /// It reads the content of the section.
  2363     virtual void read(std::istream& is) {
  2364       if (!edgeLabelReader->isLabelReader()) {
  2365 	throw DataFormatError("Cannot find undirected edgeset or label map");
  2366       }
  2367       if (!uedgeLabelReader->isLabelReader()) {
  2368 	throw DataFormatError("Cannot find undirected edgeset or label map");
  2369       }
  2370       std::string line;
  2371       while (getline(is, line)) {
  2372 	std::istringstream ls(line);
  2373 	std::string id;
  2374 	ls >> id;
  2375 	{
  2376 	  typename UEdgeReaders::iterator it = uedgeReaders.find(id);
  2377 	  if (it != uedgeReaders.end()) {
  2378 	    it->second.read(uedgeLabelReader->read(ls));
  2379 	    it->second.touch();
  2380 	    continue;
  2381 	  }	
  2382 	} {
  2383 	  typename EdgeReaders::iterator it = edgeReaders.find(id);
  2384 	  if (it != edgeReaders.end()) {
  2385 	    it->second.read(edgeLabelReader->read(ls));
  2386 	    it->second.touch();
  2387 	    continue;
  2388 	  }	
  2389 	}
  2390       }
  2391       for (typename EdgeReaders::iterator it = edgeReaders.begin();
  2392 	   it != edgeReaders.end(); ++it) {
  2393 	if (!it->second.touched()) {
  2394 	  ErrorMessage msg;
  2395 	  msg << "Edge not found in file: " << it->first;
  2396 	  throw IoParameterError(msg.message());
  2397 	}
  2398       }
  2399       for (typename UEdgeReaders::iterator it = uedgeReaders.begin();
  2400 	   it != uedgeReaders.end(); ++it) {
  2401 	if (!it->second.touched()) {
  2402 	  ErrorMessage msg;
  2403 	  msg << "UEdge not found in file: " << it->first;
  2404 	  throw IoParameterError(msg.message());
  2405 	}
  2406       }
  2407     }
  2408 
  2409     virtual void missing() {
  2410       if (edgeReaders.empty() && uedgeReaders.empty()) return;
  2411       ErrorMessage msg;
  2412       msg << "UEdges section not found in file: @uedges " << name;
  2413       throw IoParameterError(msg.message());
  2414     }
  2415     
  2416   private:
  2417 
  2418     std::string name;
  2419 
  2420     typedef std::map<std::string, 
  2421 		     _reader_bits::ItemStore<UEdge> > UEdgeReaders;
  2422     UEdgeReaders uedgeReaders;
  2423     std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uedgeLabelReader;
  2424 
  2425     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  2426     EdgeReaders edgeReaders;
  2427     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
  2428   };
  2429 
  2430   /// \ingroup section_io
  2431   /// \brief SectionReader for attributes.
  2432   ///
  2433   /// The lemon format can store multiple attribute set. Each set has
  2434   /// the header line \c \@attributes \c attributeset_name, but the 
  2435   /// attributeset_name may be empty.
  2436   ///
  2437   /// The attributeset section contains several lines. Each of them starts
  2438   /// with an attribute and then a the value for the id.
  2439   ///
  2440   /// \relates LemonReader
  2441   template <typename _Traits = DefaultReaderTraits>
  2442   class AttributeReader : public LemonReader::SectionReader {
  2443     typedef LemonReader::SectionReader Parent;
  2444     typedef _Traits Traits; 
  2445   public:
  2446     /// \brief Constructor.
  2447     ///
  2448     /// Constructor for AttributeReader. It creates the AttributeReader and
  2449     /// attach it into the given LemonReader. The reader process a section
  2450     /// only if the \c section_name and the \c _name are the same.
  2451     AttributeReader(LemonReader& _reader, 
  2452 		    const std::string& _name = std::string()) 
  2453       : Parent(_reader), name(_name) {}
  2454 
  2455     /// \brief Destructor.
  2456     ///
  2457     /// Destructor for AttributeReader.
  2458     virtual ~AttributeReader() {
  2459       for (typename Readers::iterator it = readers.begin(); 
  2460 	   it != readers.end(); ++it) {
  2461 	delete it->second;
  2462       }
  2463     }
  2464 
  2465   private:
  2466     AttributeReader(const AttributeReader&);
  2467     void operator=(AttributeReader&);
  2468 
  2469   public:
  2470     /// \brief Add an attribute reader command for the reader.
  2471     ///
  2472     /// Add an attribute reader command for the reader.
  2473     template <typename Value>
  2474     AttributeReader& readAttribute(const std::string& label, Value& value) {
  2475       return readAttribute<typename Traits::template Reader<Value> >
  2476 	(label, value);
  2477     }
  2478 
  2479     /// \brief Add an attribute reader command for the reader.
  2480     ///
  2481     /// Add an attribute reader command for the reader.
  2482     template <typename ItemReader, typename Value>
  2483     AttributeReader& readAttribute(const std::string& label, Value& value,
  2484 				   const ItemReader& ir = ItemReader()) {
  2485       checkConcept<_reader_bits::ItemReader<Value>, ItemReader>();
  2486       if (readers.find(label) != readers.end()) {
  2487 	ErrorMessage msg;
  2488 	msg << "Multiple read rule for attribute: " << label;
  2489 	throw IoParameterError(msg.message());
  2490       }
  2491       readers.insert(make_pair(label, new _reader_bits::
  2492 			       ValueReader<Value, ItemReader>(value, ir)));
  2493       return *this;
  2494     }
  2495 
  2496   protected:
  2497 
  2498     /// \brief Gives back true when the SectionReader can process 
  2499     /// the section with the given header line.
  2500     ///
  2501     /// It gives back true when the header line start with \c \@attributes,
  2502     /// and the header line's id and the attributeset's id are the same.
  2503     bool header(const std::string& line) {
  2504       std::istringstream ls(line);
  2505       std::string command;
  2506       std::string id;
  2507       ls >> command >> id;
  2508       return command == "@attributes" && name == id;
  2509     }
  2510 
  2511     /// \brief Reader function of the section.
  2512     ///
  2513     /// It reads the content of the section.
  2514     void read(std::istream& is) {
  2515       std::string line;
  2516       while (getline(is, line)) {
  2517 	std::istringstream ls(line);
  2518 	std::string id;
  2519 	ls >> id;
  2520 	typename Readers::iterator it = readers.find(id);
  2521 	if (it != readers.end()) {
  2522 	  it->second->read(ls);
  2523  	  it->second->touch();
  2524 	}
  2525       }
  2526       for (typename Readers::iterator it = readers.begin();
  2527 	   it != readers.end(); ++it) {
  2528 	if (!it->second->touched()) {
  2529 	  ErrorMessage msg;
  2530 	  msg << "Attribute not found in file: " << it->first;
  2531 	  throw IoParameterError(msg.message());
  2532 	}	
  2533       }
  2534     }    
  2535     
  2536     virtual void missing() {
  2537       if (readers.empty()) return;
  2538       ErrorMessage msg;
  2539       msg << "Attribute section not found in file: @attributes " << name;
  2540       throw IoParameterError(msg.message());
  2541     }
  2542 
  2543   private:
  2544     std::string name;
  2545 
  2546     typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers;
  2547     Readers readers;  
  2548   };
  2549 
  2550   /// \ingroup section_io
  2551   /// \brief SectionReader for reading extra node maps.
  2552   ///
  2553   /// The lemon format can store maps in the nodeset sections. This
  2554   /// class let you make distinict section to store maps.  The main
  2555   /// purpose of this class is a logical separation of some maps. The
  2556   /// other useful application could be to store paths in node maps.
  2557   ///
  2558   /// The first line of the section contains the names of the maps
  2559   /// separated with white spaces. Each next line describes an item
  2560   /// in the itemset, and contains in the first column the label of
  2561   /// the item and then the mapped values for each map.
  2562   ///
  2563   /// \relates LemonReader
  2564   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  2565   class NodeMapReader : public LemonReader::SectionReader {
  2566     typedef LemonReader::SectionReader Parent;
  2567   public:
  2568 
  2569     typedef _Graph Graph;
  2570     typedef typename Graph::Node Node;
  2571     typedef _Traits Traits;
  2572     typedef typename Traits::Skipper DefaultSkipper;
  2573 
  2574     /// \brief Constructor.
  2575     ///
  2576     /// Constructor for NodeMapReader. It creates the NodeMapReader and
  2577     /// attach it into the given LemonReader. The reader will read
  2578     /// the section when the \c section_name and the \c _name are the same.
  2579     template <typename _LabelReader>
  2580     NodeMapReader(LemonReader& _reader, 
  2581 		  const Graph& _graph, 
  2582 		  const _LabelReader& _labelReader,
  2583 		  const std::string& _name = std::string(),
  2584 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
  2585       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
  2586       labelReader.reset(new _reader_bits::
  2587 			LabelReader<Node, _LabelReader>(_labelReader));
  2588     } 
  2589 
  2590 
  2591     /// \brief Destructor.
  2592     ///
  2593     /// Destructor for NodeMapReader.
  2594     virtual ~NodeMapReader() {
  2595       for (typename MapReaders::iterator it = readers.begin(); 
  2596 	   it != readers.end(); ++it) {
  2597 	delete it->second;
  2598       }
  2599     }
  2600 
  2601   private:
  2602     NodeMapReader(const NodeMapReader&);
  2603     void operator=(const NodeMapReader&);
  2604   
  2605   public:
  2606 
  2607     /// \brief Add a new node map reader command for the reader.
  2608     ///
  2609     /// Add a new node map reader command for the reader.
  2610     template <typename Map>
  2611     NodeMapReader& readNodeMap(std::string label, Map& map) {
  2612       return _readMap<
  2613 	typename Traits::template Reader<typename Map::Value>, Map,
  2614 	typename _reader_bits::Arg<Map>::Type>(label, map);
  2615     }
  2616 
  2617     template <typename Map>
  2618     NodeMapReader& readNodeMap(std::string label, const Map& map) {
  2619       return _readMap<
  2620 	typename Traits::template Reader<typename Map::Value>, Map,
  2621 	typename _reader_bits::Arg<Map>::Type>(label, map);
  2622     }
  2623 
  2624     /// \brief Add a new node map reader command for the reader.
  2625     ///
  2626     /// Add a new node map reader command for the reader.
  2627     template <typename ItemReader, typename Map>
  2628     NodeMapReader& readNodeMap(std::string label, Map& map, 
  2629 			       const ItemReader& ir = ItemReader()) {
  2630       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  2631 	(label, map, ir);
  2632     }
  2633 
  2634     template <typename ItemReader, typename Map>
  2635     NodeMapReader& readNodeMap(std::string label, const Map& map, 
  2636 			       const ItemReader& ir = ItemReader()) {
  2637       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  2638 	(label, map, ir);
  2639     }
  2640 
  2641   private:
  2642 
  2643     template <typename ItemReader, typename Map, typename MapParameter>
  2644     NodeMapReader& _readMap(std::string label, MapParameter map, 
  2645 			   const ItemReader& ir = ItemReader()) {
  2646       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
  2647       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  2648       if (readers.find(label) != readers.end()) {
  2649 	ErrorMessage msg;
  2650 	msg << "Multiple read rule for map: " << label;
  2651 	throw IoParameterError(msg.message());
  2652       }      
  2653       readers.insert(
  2654 	make_pair(label, new _reader_bits::
  2655 		  MapReader<Node, Map, ItemReader>(map, ir)));
  2656       return *this;
  2657     }
  2658 
  2659   public:
  2660 
  2661     /// \brief Add a new node map skipper command for the reader.
  2662     ///
  2663     /// Add a new node map skipper command for the reader.
  2664     template <typename ItemReader>
  2665     NodeMapReader& skipNodeMap(std::string label, 
  2666 			       const ItemReader& ir = ItemReader()) {
  2667       if (readers.find(label) != readers.end()) {
  2668 	ErrorMessage msg;
  2669 	msg << "Multiple read rule for map: " << label;
  2670 	throw IoParameterError(msg.message());
  2671       }
  2672       readers.insert(make_pair(label, new _reader_bits::
  2673 			       SkipReader<Node, ItemReader>(ir)));
  2674       return *this;
  2675     }
  2676 
  2677   protected:
  2678 
  2679     /// \brief Gives back true when the SectionReader can process 
  2680     /// the section with the given header line.
  2681     ///
  2682     /// It gives back true when the header line starts with \c \@mapset,
  2683     /// and the header line's name and the mapset's name are the same.
  2684     virtual bool header(const std::string& line) {
  2685       std::istringstream ls(line);
  2686       std::string command;
  2687       std::string id;
  2688       ls >> command >> id;
  2689       return command == "@nodemaps" && name == id;
  2690     }
  2691 
  2692     /// \brief Reader function of the section.
  2693     ///
  2694     /// It reads the content of the section.
  2695     virtual void read(std::istream& is) {
  2696       std::vector<_reader_bits::MapReaderBase<Node>* > index;
  2697       std::string line;
  2698 
  2699       {
  2700         getline(is, line);
  2701         std::istringstream ls(line);
  2702         std::string id;
  2703         while (ls >> id) {
  2704           typename MapReaders::iterator it = readers.find(id);
  2705           if (it != readers.end()) {
  2706             it->second->touch();
  2707             index.push_back(it->second);
  2708           } else {
  2709             index.push_back(&skipper);
  2710           }
  2711         }
  2712       }
  2713       for (typename MapReaders::iterator it = readers.begin();
  2714 	   it != readers.end(); ++it) {
  2715 	if (!it->second->touched()) {
  2716 	  ErrorMessage msg;
  2717 	  msg << "Map not found in file: " << it->first;
  2718 	  throw IoParameterError(msg.message());
  2719 	}
  2720       }
  2721       while (getline(is, line)) {	
  2722 	std::istringstream ls(line);
  2723 	Node node = labelReader->read(ls);
  2724 	for (int i = 0; i < int(index.size()); ++i) {
  2725 	  index[i]->read(ls, node);
  2726 	}
  2727       }
  2728     }
  2729 
  2730     virtual void missing() {
  2731       if (readers.empty()) return;
  2732       ErrorMessage msg;
  2733       msg << "NodeMap section not found in file: @nodemaps " << name;
  2734       throw IoParameterError(msg.message());
  2735     }
  2736 
  2737   private:
  2738 
  2739     typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
  2740     MapReaders readers;
  2741    
  2742     const Graph& graph;   
  2743     std::string name;
  2744     _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
  2745     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > labelReader;
  2746 
  2747   };
  2748 
  2749   /// \ingroup section_io
  2750   /// \brief SectionReader for reading extra edge maps.
  2751   ///
  2752   /// The lemon format can store maps in the edgeset sections. This
  2753   /// class let you make distinict section to store maps.  The main
  2754   /// purpose of this class is a logical separation of some maps. The
  2755   /// other useful application could be to store paths in edge maps.
  2756   ///
  2757   /// The first line of the section contains the names of the maps
  2758   /// separated with white spaces. Each next line describes an item
  2759   /// in the itemset, and contains in the first column the label of
  2760   /// the item and then the mapped values for each map.
  2761   ///
  2762   /// \relates LemonReader
  2763   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  2764   class EdgeMapReader : public LemonReader::SectionReader {
  2765     typedef LemonReader::SectionReader Parent;
  2766   public:
  2767 
  2768     typedef _Graph Graph;
  2769     typedef typename Graph::Edge Edge;
  2770     typedef _Traits Traits;
  2771     typedef typename Traits::Skipper DefaultSkipper;
  2772 
  2773     /// \brief Constructor.
  2774     ///
  2775     /// Constructor for EdgeMapReader. It creates the EdgeMapReader and
  2776     /// attach it into the given LemonReader. The reader will read
  2777     /// the section when the \c section_name and the \c _name are the same.
  2778     template <typename _LabelReader>
  2779     EdgeMapReader(LemonReader& _reader, 
  2780 		   const Graph& _graph, 
  2781 		   const _LabelReader& _labelReader,
  2782 		   const std::string& _name = std::string(),
  2783 		   const DefaultSkipper& _skipper = DefaultSkipper()) 
  2784       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
  2785       labelReader.reset(new _reader_bits::
  2786 			LabelReader<Edge, _LabelReader>(_labelReader));
  2787     } 
  2788 
  2789 
  2790     /// \brief Destructor.
  2791     ///
  2792     /// Destructor for EdgeMapReader.
  2793     virtual ~EdgeMapReader() {
  2794       for (typename MapReaders::iterator it = readers.begin(); 
  2795 	   it != readers.end(); ++it) {
  2796 	delete it->second;
  2797       }
  2798     }
  2799 
  2800   private:
  2801     EdgeMapReader(const EdgeMapReader&);
  2802     void operator=(const EdgeMapReader&);
  2803   
  2804   public:
  2805 
  2806     /// \brief Add a new edge map reader command for the reader.
  2807     ///
  2808     /// Add a new edge map reader command for the reader.
  2809     template <typename Map>
  2810     EdgeMapReader& readEdgeMap(std::string label, Map& map) {
  2811       return _readMap<
  2812 	typename Traits::template Reader<typename Map::Value>, Map,
  2813 	typename _reader_bits::Arg<Map>::Type>(label, map);
  2814     }
  2815 
  2816     template <typename Map>
  2817     EdgeMapReader& readEdgeMap(std::string label, const Map& map) {
  2818       return _readMap<
  2819 	typename Traits::template Reader<typename Map::Value>, Map,
  2820 	typename _reader_bits::Arg<Map>::Type>(label, map);
  2821     }
  2822 
  2823     /// \brief Add a new edge map reader command for the reader.
  2824     ///
  2825     /// Add a new edge map reader command for the reader.
  2826     template <typename ItemReader, typename Map>
  2827     EdgeMapReader& readEdgeMap(std::string label, Map& map, 
  2828 			  const ItemReader& ir = ItemReader()) {
  2829       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  2830 	(label, map, ir);
  2831     }
  2832 
  2833     template <typename ItemReader, typename Map>
  2834     EdgeMapReader& readEdgeMap(std::string label, const Map& map, 
  2835 			  const ItemReader& ir = ItemReader()) {
  2836       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  2837 	(label, map, ir);
  2838     }
  2839 
  2840   private:
  2841 
  2842     template <typename ItemReader, typename Map, typename MapParameter>
  2843     EdgeMapReader& _readMap(std::string label, MapParameter map, 
  2844 				const ItemReader& ir = ItemReader()) {
  2845       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
  2846       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  2847       if (readers.find(label) != readers.end()) {
  2848 	ErrorMessage msg;
  2849 	msg << "Multiple read rule for map: " << label;
  2850 	throw IoParameterError(msg.message());
  2851       }      
  2852       readers.insert(
  2853 	make_pair(label, new _reader_bits::
  2854 		  MapReader<Edge, Map, ItemReader>(map, ir)));
  2855       return *this;
  2856     }
  2857 
  2858   public:
  2859 
  2860     /// \brief Add a new edge map skipper command for the reader.
  2861     ///
  2862     /// Add a new edge map skipper command for the reader.
  2863     template <typename ItemReader>
  2864     EdgeMapReader& skipEdgeMap(std::string label, 
  2865 			  const ItemReader& ir = ItemReader()) {
  2866       if (readers.find(label) != readers.end()) {
  2867 	ErrorMessage msg;
  2868 	msg << "Multiple read rule for map: " << label;
  2869 	throw IoParameterError(msg.message());
  2870       }
  2871       readers.insert(make_pair(label, new _reader_bits::
  2872 			       SkipReader<Edge, ItemReader>(ir)));
  2873       return *this;
  2874     }
  2875 
  2876   protected:
  2877 
  2878     /// \brief Gives back true when the SectionReader can process 
  2879     /// the section with the given header line.
  2880     ///
  2881     /// It gives back true when the header line starts with \c \@mapset,
  2882     /// and the header line's name and the mapset's name are the same.
  2883     virtual bool header(const std::string& line) {
  2884       std::istringstream ls(line);
  2885       std::string command;
  2886       std::string id;
  2887       ls >> command >> id;
  2888       return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
  2889     }
  2890 
  2891     /// \brief Reader function of the section.
  2892     ///
  2893     /// It reads the content of the section.
  2894     virtual void read(std::istream& is) {
  2895       std::vector<_reader_bits::MapReaderBase<Edge>* > index;
  2896       std::string line;
  2897 
  2898       {
  2899         getline(is, line);
  2900         std::istringstream ls(line);
  2901         std::string id;
  2902         while (ls >> id) {
  2903           typename MapReaders::iterator it = readers.find(id);
  2904           if (it != readers.end()) {
  2905             it->second->touch();
  2906             index.push_back(it->second);
  2907           } else {
  2908             index.push_back(&skipper);
  2909           }
  2910         }
  2911       }
  2912       for (typename MapReaders::iterator it = readers.begin();
  2913 	   it != readers.end(); ++it) {
  2914 	if (!it->second->touched()) {
  2915 	  ErrorMessage msg;
  2916 	  msg << "Map not found in file: " << it->first;
  2917 	  throw IoParameterError(msg.message());
  2918 	}
  2919       }
  2920       while (getline(is, line)) {	
  2921 	std::istringstream ls(line);
  2922 	Edge edge = labelReader->read(ls);
  2923 	for (int i = 0; i < int(index.size()); ++i) {
  2924 	  index[i]->read(ls, edge);
  2925 	}
  2926       }
  2927     }
  2928 
  2929     virtual void missing() {
  2930       if (readers.empty()) return;
  2931       ErrorMessage msg;
  2932       msg << "EdgeMap section not found in file: @edgemaps " << name;
  2933       throw IoParameterError(msg.message());
  2934     }
  2935 
  2936   private:
  2937 
  2938     typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
  2939     MapReaders readers;
  2940    
  2941     const Graph& graph;   
  2942     std::string name;
  2943     _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
  2944     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > labelReader;
  2945 
  2946   };
  2947 
  2948   /// \ingroup section_io
  2949   /// \brief SectionReader for reading extra undirected edge maps.
  2950   ///
  2951   /// The lemon format can store maps in the uedgeset sections. This
  2952   /// class let you make distinict section to store maps.  The main
  2953   /// purpose of this class is a logical separation of some maps. The
  2954   /// other useful application could be to store paths in undirected
  2955   /// edge maps.
  2956   ///
  2957   /// The first line of the section contains the names of the maps
  2958   /// separated with white spaces. Each next line describes an item
  2959   /// in the itemset, and contains in the first column the label of
  2960   /// the item and then the mapped values for each map.
  2961   ///
  2962   /// \relates LemonReader
  2963   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  2964   class UEdgeMapReader : public LemonReader::SectionReader {
  2965     typedef LemonReader::SectionReader Parent;
  2966   public:
  2967 
  2968     typedef _Graph Graph;
  2969     typedef typename Graph::Edge Edge;
  2970     typedef typename Graph::UEdge UEdge;
  2971     typedef _Traits Traits;
  2972     typedef typename Traits::Skipper DefaultSkipper;
  2973 
  2974     /// \brief Constructor.
  2975     ///
  2976     /// Constructor for UEdgeMapReader. It creates the UEdgeMapReader and
  2977     /// attach it into the given LemonReader. The reader will read
  2978     /// the section when the \c section_name and the \c _name are the same.
  2979     template <typename _LabelReader>
  2980     UEdgeMapReader(LemonReader& _reader, const Graph& _graph, 
  2981 		   const _LabelReader& _labelReader,
  2982 		   const std::string& _name = std::string(),
  2983 		   const DefaultSkipper& _skipper = DefaultSkipper()) 
  2984       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
  2985       labelReader.reset(new _reader_bits::
  2986 			LabelReader<UEdge, _LabelReader>(_labelReader));
  2987     } 
  2988 
  2989 
  2990     /// \brief Destructor.
  2991     ///
  2992     /// Destructor for UEdgeMapReader.
  2993     virtual ~UEdgeMapReader() {
  2994       for (typename MapReaders::iterator it = readers.begin(); 
  2995 	   it != readers.end(); ++it) {
  2996 	delete it->second;
  2997       }
  2998     }
  2999 
  3000   private:
  3001     UEdgeMapReader(const UEdgeMapReader&);
  3002     void operator=(const UEdgeMapReader&);
  3003   
  3004   public:
  3005 
  3006     /// \brief Add a new undirected edge map reader command for the
  3007     /// reader.
  3008     ///
  3009     /// Add a new undirected edge map reader command for the reader.
  3010     template <typename Map>
  3011     UEdgeMapReader& readUEdgeMap(std::string label, Map& map) {
  3012       return _readMap<
  3013 	typename Traits::template Reader<typename Map::Value>, Map,
  3014 	typename _reader_bits::Arg<Map>::Type>(label, map);
  3015     }
  3016 
  3017     template <typename Map>
  3018     UEdgeMapReader& readUEdgeMap(std::string label, const Map& map) {
  3019       return _readMap<
  3020 	typename Traits::template Reader<typename Map::Value>, Map,
  3021 	typename _reader_bits::Arg<Map>::Type>(label, map);
  3022     }
  3023 
  3024     /// \brief Add a new undirected edge map reader command for the
  3025     /// reader.
  3026     ///
  3027     /// Add a new undirected edge map reader command for the reader.
  3028     template <typename ItemReader, typename Map>
  3029     UEdgeMapReader& readUEdgeMap(std::string label, Map& map, 
  3030 			  const ItemReader& ir = ItemReader()) {
  3031       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  3032 	(label, map, ir);
  3033     }
  3034 
  3035     template <typename ItemReader, typename Map>
  3036     UEdgeMapReader& readUEdgeMap(std::string label, const Map& map, 
  3037 			  const ItemReader& ir = ItemReader()) {
  3038       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  3039 	(label, map, ir);
  3040     }
  3041 
  3042   private:
  3043 
  3044     template <typename ItemReader, typename Map, typename MapParameter>
  3045     UEdgeMapReader& _readMap(std::string label, MapParameter map, 
  3046 				const ItemReader& ir = ItemReader()) {
  3047       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
  3048       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  3049       if (readers.find(label) != readers.end()) {
  3050 	ErrorMessage msg;
  3051 	msg << "Multiple read rule for map: " << label;
  3052 	throw IoParameterError(msg.message());
  3053       }      
  3054       readers.insert(
  3055 	make_pair(label, new _reader_bits::
  3056 		  MapReader<UEdge, Map, ItemReader>(map, ir)));
  3057       return *this;
  3058     }
  3059 
  3060   public:
  3061 
  3062     /// \brief Add a new undirected edge map skipper command for the
  3063     /// reader.
  3064     ///
  3065     /// Add a new undirected edge map skipper command for the reader.
  3066     template <typename ItemReader>
  3067     UEdgeMapReader& skipUEdgeMap(std::string label, 
  3068 			  const ItemReader& ir = ItemReader()) {
  3069       if (readers.find(label) != readers.end()) {
  3070 	ErrorMessage msg;
  3071 	msg << "Multiple read rule for map: " << label;
  3072 	throw IoParameterError(msg.message());
  3073       }
  3074       readers.insert(make_pair(label, new _reader_bits::
  3075 			       SkipReader<Edge, ItemReader>(ir)));
  3076       return *this;
  3077     }
  3078 
  3079     /// \brief Add a new directed edge map reader command for the reader.
  3080     ///
  3081     /// Add a new directed edge map reader command for the reader.
  3082     template <typename Map>
  3083     UEdgeMapReader& readEdgeMap(std::string label, Map& map) {
  3084       return _readDirMap<
  3085 	typename Traits::template Reader<typename Map::Value>, Map,
  3086 	typename _reader_bits::Arg<Map>::Type>(label, map);
  3087     }
  3088 
  3089     template <typename Map>
  3090     UEdgeMapReader& readEdgeMap(std::string label, const Map& map) {
  3091       return _readDirMap<
  3092 	typename Traits::template Reader<typename Map::Value>, Map,
  3093 	typename _reader_bits::Arg<Map>::Type>(label, map);
  3094     }
  3095 
  3096     /// \brief Add a new directed edge map reader command for the reader.
  3097     ///
  3098     /// Add a new directed edge map reader command for the reader.
  3099     template <typename ItemReader, typename Map>
  3100     UEdgeMapReader& readEdgeMap(std::string label, Map& map, 
  3101 				    const ItemReader& ir = ItemReader()) {
  3102       return _readDirMap<ItemReader, Map, 
  3103         typename _reader_bits::Arg<Map>::Type>(label, map, ir);
  3104     }
  3105 
  3106     template <typename ItemReader, typename Map>
  3107     UEdgeMapReader& readEdgeMap(std::string label, const Map& map, 
  3108 				    const ItemReader& ir = ItemReader()) {
  3109       return _readDirMap<ItemReader, Map, 
  3110         typename _reader_bits::Arg<Map>::Type>(label, map, ir);
  3111     }
  3112 
  3113   private:
  3114 
  3115     template <typename ItemReader, typename Map, typename MapParameter>
  3116     UEdgeMapReader& _readDirMap(std::string label, MapParameter map,
  3117 				    const ItemReader& ir = ItemReader()) { 
  3118       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  3119       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
  3120       readUEdgeMap("+" + label, 
  3121                    _reader_bits::forwardComposeMap(graph, map), ir);
  3122       readUEdgeMap("-" + label, 
  3123                    _reader_bits::backwardComposeMap(graph, map), ir);
  3124       return *this;      
  3125     }
  3126 
  3127   public:
  3128 
  3129     /// \brief Add a new directed edge map skipper command for the reader.
  3130     ///
  3131     /// Add a new directed edge map skipper command for the reader.
  3132     template <typename ItemReader>
  3133     UEdgeMapReader& skipEdgeMap(std::string label, 
  3134                                 const ItemReader& ir = ItemReader()) {
  3135       skipUEdgeMap("+" + label, ir);
  3136       skipUEdgeMap("-" + label, ir);
  3137       return *this;
  3138     }
  3139 
  3140   protected:
  3141 
  3142     /// \brief Gives back true when the SectionReader can process 
  3143     /// the section with the given header line.
  3144     ///
  3145     /// It gives back true when the header line starts with \c \@mapset,
  3146     /// and the header line's name and the mapset's name are the same.
  3147     virtual bool header(const std::string& line) {
  3148       std::istringstream ls(line);
  3149       std::string command;
  3150       std::string id;
  3151       ls >> command >> id;
  3152       return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
  3153     }
  3154 
  3155     /// \brief Reader function of the section.
  3156     ///
  3157     /// It reads the content of the section.
  3158     virtual void read(std::istream& is) {
  3159       std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
  3160       std::string line;
  3161 
  3162       {
  3163         getline(is, line);
  3164         std::istringstream ls(line);
  3165         std::string id;
  3166         while (ls >> id) {
  3167           typename MapReaders::iterator it = readers.find(id);
  3168           if (it != readers.end()) {
  3169             it->second->touch();
  3170             index.push_back(it->second);
  3171           } else {
  3172             index.push_back(&skipper);
  3173           }
  3174         }
  3175       }
  3176       for (typename MapReaders::iterator it = readers.begin();
  3177 	   it != readers.end(); ++it) {
  3178 	if (!it->second->touched()) {
  3179 	  ErrorMessage msg;
  3180 	  msg << "Map not found in file: " << it->first;
  3181 	  throw IoParameterError(msg.message());
  3182 	}
  3183       }
  3184       while (getline(is, line)) {	
  3185 	std::istringstream ls(line);
  3186 	UEdge uedge = labelReader->read(ls);
  3187 	for (int i = 0; i < int(index.size()); ++i) {
  3188 	  index[i]->read(ls, uedge);
  3189 	}
  3190       }
  3191     }
  3192 
  3193     virtual void missing() {
  3194       if (readers.empty()) return;
  3195       ErrorMessage msg;
  3196       msg << "UEdgeMap section not found in file: @uedgemaps " << name;
  3197       throw IoParameterError(msg.message());
  3198     }
  3199 
  3200   private:
  3201 
  3202     const Graph& graph;   
  3203     std::string name;
  3204 
  3205     typedef std::map<std::string, 
  3206 		     _reader_bits::MapReaderBase<UEdge>*> MapReaders;
  3207    
  3208     MapReaders readers;
  3209     _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
  3210 
  3211     std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > labelReader;
  3212 
  3213   };
  3214 
  3215   /// \ingroup section_io
  3216   /// \brief SectionReader for retrieve what is in the file.
  3217   ///
  3218   /// SectionReader for retrieve what is in the file. If you want
  3219   /// to know which sections, maps and items are in the file
  3220   /// use the next code:
  3221   ///\code
  3222   /// LemonReader reader("input.lgf");
  3223   /// ContentReader content(reader);
  3224   /// reader.run();
  3225   ///\endcode
  3226   class ContentReader : public LemonReader::SectionReader {
  3227     typedef LemonReader::SectionReader Parent;
  3228   public:
  3229     /// \brief Constructor.
  3230     ///
  3231     /// Constructor for
  3232     ContentReader(LemonReader& _reader) : Parent(_reader) {}
  3233 
  3234     /// \brief Desctructor.
  3235     ///
  3236     /// Desctructor.
  3237     virtual ~ContentReader() {}
  3238 
  3239     /// \brief Gives back how many nodesets are in the file.
  3240     ///
  3241     /// Gives back how many nodesets are in the file.
  3242     int nodeSetNum() const {
  3243       return nodesets.size();
  3244     }
  3245 
  3246     /// \brief Gives back the name of nodeset on the indiced position.
  3247     ///
  3248     /// Gives back the name of nodeset on the indiced position.
  3249     std::string nodeSetName(int index) const {
  3250       return nodesets[index].name;
  3251     }
  3252 
  3253     /// \brief Gives back the map names of nodeset on the indiced position.
  3254     ///
  3255     /// Gives back the map names of nodeset on the indiced position.
  3256     const std::vector<std::string>& nodeSetMaps(int index) const {
  3257       return nodesets[index].items;
  3258     }
  3259 
  3260     /// \brief Gives back how many edgesets are in the file.
  3261     ///
  3262     /// Gives back how many edgesets are in the file.
  3263     int edgeSetNum() const {
  3264       return edgesets.size();
  3265     }
  3266 
  3267     /// \brief Gives back the name of edgeset on the indiced position.
  3268     ///
  3269     /// Gives back the name of edgeset on the indiced position.
  3270     std::string edgeSetName(int index) const {
  3271       return edgesets[index].name;
  3272     }
  3273 
  3274     /// \brief Gives back the map names of edgeset on the indiced position.
  3275     ///
  3276     /// Gives back the map names of edgeset on the indiced position.
  3277     const std::vector<std::string>& edgeSetMaps(int index) const {
  3278       return edgesets[index].items;
  3279     }
  3280 
  3281     /// \brief Gives back how many undirected edgesets are in the file.
  3282     ///
  3283     /// Gives back how many undirected edgesets are in the file.
  3284     int uEdgeSetNum() const {
  3285       return uedgesets.size();
  3286     }
  3287 
  3288     /// \brief Gives back the name of undirected edgeset on the indiced 
  3289     /// position.
  3290     ///
  3291     /// Gives back the name of undirected edgeset on the indiced position.
  3292     std::string uEdgeSetName(int index) const {
  3293       return uedgesets[index].name;
  3294     }
  3295 
  3296     /// \brief Gives back the map names of undirected edgeset on the indiced 
  3297     /// position.
  3298     ///
  3299     /// Gives back the map names of undirected edgeset on the indiced position.
  3300     const std::vector<std::string>& uEdgeSetMaps(int index) const {
  3301       return uedgesets[index].items;
  3302     }
  3303 
  3304     /// \brief Gives back how many labeled nodes section are in the file.
  3305     ///
  3306     /// Gives back how many labeled nodes section are in the file.
  3307     int nodesNum() const {
  3308       return nodes.size();
  3309     }
  3310 
  3311     /// \brief Gives back the name of labeled nodes section on the indiced 
  3312     /// position.
  3313     ///
  3314     /// Gives back the name of labeled nodes section on the indiced position.
  3315     std::string nodesName(int index) const {
  3316       return nodes[index].name;
  3317     }
  3318 
  3319     /// \brief Gives back the names of the labeled nodes in the indiced 
  3320     /// section.
  3321     ///
  3322     /// Gives back the names of the labeled nodes in the indiced section.
  3323     const std::vector<std::string>& nodesItems(int index) const {
  3324       return nodes[index].items;
  3325     }
  3326 
  3327     /// \brief Gives back how many labeled edges section are in the file.
  3328     ///
  3329     /// Gives back how many labeled edges section are in the file.
  3330     int edgesNum() const {
  3331       return edges.size();
  3332     }
  3333 
  3334     /// \brief Gives back the name of labeled edges section on the indiced 
  3335     /// position.
  3336     ///
  3337     /// Gives back the name of labeled edges section on the indiced position.
  3338     std::string edgesName(int index) const {
  3339       return edges[index].name;
  3340     }
  3341 
  3342     /// \brief Gives back the names of the labeled edges in the indiced 
  3343     /// section.
  3344     ///
  3345     /// Gives back the names of the labeled edges in the indiced section.
  3346     const std::vector<std::string>& edgesItems(int index) const {
  3347       return edges[index].items;
  3348     }
  3349  
  3350     /// \brief Gives back how many labeled undirected edges section are 
  3351     /// in the file.
  3352     ///
  3353     /// Gives back how many labeled undirected edges section are in the file.
  3354     int uEdgesNum() const {
  3355       return uedges.size();
  3356     }
  3357 
  3358     /// \brief Gives back the name of labeled undirected edges section 
  3359     /// on the indiced position.
  3360     ///
  3361     /// Gives back the name of labeled undirected edges section on the 
  3362     /// indiced position.
  3363     std::string uEdgesName(int index) const {
  3364       return uedges[index].name;
  3365     }
  3366 
  3367     /// \brief Gives back the names of the labeled undirected edges in 
  3368     /// the indiced section.
  3369     ///
  3370     /// Gives back the names of the labeled undirected edges in the 
  3371     /// indiced section.
  3372     const std::vector<std::string>& uEdgesItems(int index) const {
  3373       return uedges[index].items;
  3374     }
  3375 
  3376  
  3377     /// \brief Gives back how many attributes section are in the file.
  3378     ///
  3379     /// Gives back how many attributes section are in the file.
  3380     int attributesNum() const {
  3381       return attributes.size();
  3382     }
  3383 
  3384     /// \brief Gives back the name of attributes section on the indiced 
  3385     /// position.
  3386     ///
  3387     /// Gives back the name of attributes section on the indiced position.
  3388     std::string attributesName(int index) const {
  3389       return attributes[index].name;
  3390     }
  3391 
  3392     /// \brief Gives back the names of the attributes in the indiced section.
  3393     ///
  3394     /// Gives back the names of the attributes in the indiced section.
  3395     const std::vector<std::string>& attributesItems(int index) const {
  3396       return attributes[index].items;
  3397     }
  3398 
  3399     const std::vector<std::string>& otherSections() const {
  3400       return sections;
  3401     }
  3402 
  3403   protected:
  3404     
  3405     /// \brief Gives back true when the SectionReader can process 
  3406     /// the section with the given header line.
  3407     ///
  3408     /// It gives back true when the section is common section.
  3409     bool header(const std::string& line) {
  3410       std::istringstream ls(line);
  3411       std::string command, name;
  3412       ls >> command >> name;
  3413       if (command == "@nodeset") {
  3414 	current = command;
  3415 	nodesets.push_back(SectionInfo(name));
  3416       } else if (command == "@edgeset") {
  3417 	current = command;
  3418 	edgesets.push_back(SectionInfo(name));
  3419       } else if (command == "@uedgeset") {
  3420 	current = command;
  3421 	uedgesets.push_back(SectionInfo(name));
  3422       } else if (command == "@nodes") {
  3423 	current = command;
  3424 	nodes.push_back(SectionInfo(name));
  3425       } else if (command == "@edges") {
  3426 	current = command;
  3427 	edges.push_back(SectionInfo(name));
  3428       } else if (command == "@uedges") {
  3429 	current = command;
  3430 	uedges.push_back(SectionInfo(name));
  3431       } else if (command == "@attributes") {
  3432 	current = command;
  3433 	attributes.push_back(SectionInfo(name));
  3434       } else {
  3435 	sections.push_back(line);
  3436 	return false;
  3437       }
  3438       return true;
  3439     }
  3440 
  3441     /// \brief Retrieve the items from various sections.
  3442     ///
  3443     /// Retrieve the items from various sections.
  3444     void read(std::istream& is) {
  3445       if (current == "@nodeset") {
  3446 	readMapNames(is, nodesets.back().items);
  3447       } else if (current == "@edgeset") {
  3448 	readMapNames(is, edgesets.back().items);
  3449       } else if (current == "@uedgeset") {
  3450 	readMapNames(is, uedgesets.back().items);
  3451       } else if (current == "@nodes") {
  3452 	readItemNames(is, nodes.back().items);
  3453       } else if (current == "@edges") {
  3454 	readItemNames(is, edges.back().items);
  3455       } else if (current == "@uedges") {
  3456 	readItemNames(is, uedges.back().items);
  3457       } else if (current == "@attributes") {
  3458 	readItemNames(is, attributes.back().items);
  3459       }
  3460     }    
  3461 
  3462   private:
  3463 
  3464     void readMapNames(std::istream& is, std::vector<std::string>& maps) {
  3465       std::string line, name;
  3466       std::getline(is, line);
  3467       std::istringstream ls(line);
  3468       while (ls >> name) {
  3469 	maps.push_back(name);
  3470       }
  3471       while (getline(is, line));
  3472     }
  3473 
  3474     void readItemNames(std::istream& is, std::vector<std::string>& maps) {
  3475       std::string line, name;
  3476       while (std::getline(is, line)) {
  3477 	std::istringstream ls(line);
  3478 	ls >> name;
  3479 	maps.push_back(name);
  3480       }
  3481     }
  3482 
  3483     struct SectionInfo {
  3484       std::string name;
  3485       std::vector<std::string> items;
  3486 
  3487       SectionInfo(const std::string& _name) : name(_name) {}
  3488     };
  3489 
  3490     std::vector<SectionInfo> nodesets;
  3491     std::vector<SectionInfo> edgesets;
  3492     std::vector<SectionInfo> uedgesets;
  3493 
  3494     std::vector<SectionInfo> nodes;
  3495     std::vector<SectionInfo> edges;
  3496     std::vector<SectionInfo> uedges;
  3497 
  3498     std::vector<SectionInfo> attributes;
  3499 
  3500     std::vector<std::string> sections;
  3501 
  3502     std::string current;
  3503 
  3504   };
  3505 
  3506 }
  3507 #endif