lemon/lemon_reader.h
author deba
Tue, 04 Dec 2007 14:08:27 +0000
changeset 2531 426a4e35e167
parent 2502 9c23c3762bc5
child 2553 bfced05fa852
permissions -rw-r--r--
rename graphs script
     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 	    } else {
  1347 	      index.push_back(&skipper);
  1348 	    }
  1349 	    if (id == "label") {
  1350 	      inverter.reset(index.back()->getInverter());
  1351 	      index.back() = inverter.get();
  1352 	    }
  1353 	  }
  1354 	}
  1355 	for (typename MapReaders::iterator it = areaders.begin();
  1356 	     it != areaders.end(); ++it) {
  1357 	  if (!it->second->touched()) {
  1358 	    ErrorMessage msg;
  1359 	    msg << "Map not found in file: " << it->first;
  1360 	    throw IoParameterError(msg.message());
  1361 	  }
  1362 	}
  1363 	for (typename MapReaders::iterator it = readers.begin();
  1364 	     it != readers.end(); ++it) {
  1365 	  if (!it->second->touched()) {
  1366 	    ErrorMessage msg;
  1367 	    msg << "Map not found in file: " << it->first;
  1368 	    throw IoParameterError(msg.message());
  1369 	  }
  1370 	  it->second->touch(false);
  1371 	}
  1372 
  1373 	while (getline(is, line)) {
  1374 	  if (line[0] == '&') {
  1375 	    std::istringstream ls(line);
  1376 	    std::string id;
  1377 	    ls >> id;
  1378 	    if (id == "&bnodeset") break;
  1379 	  }
  1380 	  Node node = graph.addANode();
  1381 	  std::istringstream ls(line);
  1382 	  for (int i = 0; i < int(index.size()); ++i) {
  1383 	    index[i]->read(ls, node);
  1384 	  }
  1385 	}
  1386       }
  1387 
  1388       {
  1389 	std::vector<_reader_bits::MapReaderBase<Node>* > index;
  1390 	{
  1391 	  std::istringstream ls(line);
  1392 	  std::string id;
  1393 	  ls >> id;
  1394 	  if (id != "&bnodeset") {
  1395 	    throw IoParameterError("Cannot find &bnodeset subsection");
  1396 	  }
  1397 	  while (ls >> id) {
  1398 	    typename MapReaders::iterator it = readers.find(id);
  1399 	    typename MapReaders::iterator bit = breaders.find(id);
  1400 	    if (it != readers.end()) {
  1401 	      it->second->touch();
  1402 	      index.push_back(it->second);
  1403 	    } else if (bit != breaders.end()) {
  1404 	      bit->second->touch();
  1405 	      index.push_back(bit->second);
  1406 	    } else {
  1407 	      index.push_back(&skipper);
  1408 	    }
  1409 	    if (id == "label" && inverter.get() != 0) {
  1410 	      index.back() = inverter.get();
  1411 	    }
  1412 	  }
  1413 	}
  1414 	for (typename MapReaders::iterator it = breaders.begin();
  1415 	     it != breaders.end(); ++it) {
  1416 	  if (!it->second->touched()) {
  1417 	    ErrorMessage msg;
  1418 	    msg << "Map not found in file: " << it->first;
  1419 	    throw IoParameterError(msg.message());
  1420 	  }
  1421 	}
  1422 	for (typename MapReaders::iterator it = readers.begin();
  1423 	     it != readers.end(); ++it) {
  1424 	  if (!it->second->touched()) {
  1425 	    ErrorMessage msg;
  1426 	    msg << "Map not found in file: " << it->first;
  1427 	    throw IoParameterError(msg.message());
  1428 	  }
  1429 	}
  1430 	while (getline(is, line)) {	
  1431 	  Node node = graph.addBNode();
  1432 	  std::istringstream ls(line);
  1433 	  for (int i = 0; i < int(index.size()); ++i) {
  1434 	    index[i]->read(ls, node);
  1435 	  }
  1436 	}
  1437       }
  1438     }
  1439 
  1440     virtual void missing() {
  1441       if (readers.empty()) return;
  1442       ErrorMessage msg;
  1443       msg << "BpNodeSet section not found in file: @bpnodeset " << name;
  1444       throw IoParameterError(msg.message());
  1445     }
  1446 
  1447   public:
  1448 
  1449     /// \brief Returns true if the nodeset can give back the node by its label.
  1450     ///
  1451     /// Returns true if the nodeset can give back the node by its label.
  1452     /// It is possible only if an "label" named map was read.
  1453     bool isLabelReader() const {
  1454       return inverter.get() != 0;
  1455     }
  1456 
  1457     /// \brief Gives back the node by its label.
  1458     ///
  1459     /// It reads an id from the stream and gives back which node belongs to
  1460     /// it. It is possible only if there was read an "label" named map.
  1461     void readLabel(std::istream& is, Node& node) const {
  1462       node = inverter->read(is);
  1463     } 
  1464 
  1465   private:
  1466 
  1467     typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> 
  1468     MapReaders;
  1469     
  1470     MapReaders areaders, breaders, readers;
  1471    
  1472     Graph& graph;
  1473     std::string name;
  1474     _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
  1475 
  1476     std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
  1477   };
  1478 
  1479 
  1480   /// \ingroup section_io
  1481   /// \brief SectionReader for reading a graph's edgeset.
  1482   ///
  1483   /// The lemon format can store multiple graph edgesets with several maps.
  1484   /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but the
  1485   /// \c edgeset_name may be empty.
  1486   ///
  1487   /// The first line of the section contains the names of the maps separated
  1488   /// with white spaces. Each next lines describes an edge in the edgeset. The
  1489   /// line contains the source and the target nodes' id and the mapped 
  1490   /// values for each map.
  1491   ///
  1492   /// If the edgeset contains an \c "label" named map then it will be regarded
  1493   /// as id map. This map should contain only unique values and when the 
  1494   /// \c readLabel() member will read a value from the given stream it will
  1495   /// give back that edge which is mapped to this value.
  1496   ///
  1497   /// The edgeset reader needs a node id reader to identify which nodes
  1498   /// have to be connected. If a NodeSetReader reads an "label" named map,
  1499   /// it will be able to resolve the nodes by ids.
  1500   ///
  1501   /// \relates LemonReader
  1502   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  1503   class EdgeSetReader : public LemonReader::SectionReader {
  1504     typedef LemonReader::SectionReader Parent;
  1505   public:
  1506 
  1507     typedef _Graph Graph;
  1508     typedef _Traits Traits;
  1509     typedef typename Graph::Node Node;
  1510     typedef typename Graph::Edge Edge;
  1511     typedef typename Traits::Skipper DefaultSkipper;
  1512 
  1513     /// \brief Constructor.
  1514     ///
  1515     /// Constructor for EdgeSetReader. It creates the EdgeSetReader and
  1516     /// attach it into the given LemonReader. The edgeset reader will
  1517     /// add the read edges to the given Graph. It will use the given
  1518     /// node id reader to read the source and target nodes of the edges.
  1519     /// The reader will read the section only if the \c _name and the 
  1520     /// \c edgset_name are the same. 
  1521     template <typename NodeLabelReader>
  1522     EdgeSetReader(LemonReader& _reader, 
  1523 		  Graph& _graph, 
  1524 		  const NodeLabelReader& _nodeLabelReader, 
  1525 		  const std::string& _name = std::string(),
  1526 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
  1527       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
  1528       checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
  1529       nodeLabelReader.reset(new _reader_bits::
  1530 			 LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
  1531     }
  1532     /// \brief Destructor.
  1533     ///
  1534     /// Destructor for EdgeSetReader.
  1535     virtual ~EdgeSetReader() {
  1536       for (typename MapReaders::iterator it = readers.begin(); 
  1537 	   it != readers.end(); ++it) {
  1538 	delete it->second;
  1539       }
  1540     }
  1541 
  1542   private:
  1543     EdgeSetReader(const EdgeSetReader&);
  1544     void operator=(const EdgeSetReader&);
  1545 
  1546   public:
  1547 
  1548     /// \brief Add a new edge map reader command for the reader.
  1549     ///
  1550     /// Add a new edge map reader command for the reader.
  1551     template <typename Map>
  1552     EdgeSetReader& readEdgeMap(std::string label, Map& map) {
  1553       return _readMap<
  1554 	typename Traits::template Reader<typename Map::Value>, Map,
  1555 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1556     }
  1557 
  1558     template <typename Map>
  1559     EdgeSetReader& readEdgeMap(std::string label, const Map& map) {
  1560       return _readMap<
  1561 	typename Traits::template Reader<typename Map::Value>, Map,
  1562 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1563     }
  1564 
  1565     /// \brief Add a new edge map reader command for the reader.
  1566     ///
  1567     /// Add a new edge map reader command for the reader.
  1568     template <typename ItemReader, typename Map>
  1569     EdgeSetReader& readEdgeMap(std::string label, Map& map, 
  1570                                const ItemReader& ir = ItemReader()) {
  1571       return _readMap<ItemReader, Map,
  1572 	typename _reader_bits::Arg<Map>::Type>(label, map, ir);
  1573     }
  1574 
  1575     template <typename ItemReader, typename Map>
  1576     EdgeSetReader& readEdgeMap(std::string label, const Map& map, 
  1577 			       const ItemReader& ir = ItemReader()) {
  1578       return _readMap<ItemReader, Map,
  1579 	typename _reader_bits::Arg<Map>::Type>(label, map, ir);
  1580     }
  1581 
  1582   private:
  1583 
  1584     template <typename ItemReader, typename Map, typename MapParameter>
  1585     EdgeSetReader& _readMap(std::string label, MapParameter map, 
  1586 			    const ItemReader& ir = ItemReader()) {
  1587       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
  1588       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  1589       if (readers.find(label) != readers.end()) {
  1590 	ErrorMessage msg;
  1591 	msg << "Multiple read rule for edge map: " << label;
  1592 	throw IoParameterError(msg.message());
  1593       }
  1594       readers.insert(
  1595 	make_pair(label, new _reader_bits::
  1596 		  MapReader<Edge, Map, ItemReader>(map, ir)));
  1597       return *this;
  1598     }
  1599 
  1600   public:
  1601 
  1602     /// \brief Add a new edge map skipper command for the reader.
  1603     ///
  1604     /// Add a new edge map skipper command for the reader.
  1605     template <typename ItemReader>
  1606     EdgeSetReader& skipEdgeMap(std::string label, 
  1607 			       const ItemReader& ir = ItemReader()) {
  1608       if (readers.find(label) != readers.end()) {
  1609 	ErrorMessage msg;
  1610 	msg << "Multiple read rule for edge map: " << label;
  1611 	throw IoParameterError(msg.message());
  1612       }
  1613       readers.insert(make_pair(label, new _reader_bits::
  1614 			       SkipReader<Edge, ItemReader>(ir)));
  1615       return *this;
  1616     }
  1617 
  1618   protected:
  1619 
  1620     /// \brief Gives back true when the SectionReader can process 
  1621     /// the section with the given header line.
  1622     ///
  1623     /// It gives back true when the header line starts with \c \@edgeset,
  1624     /// and the header line's name and the edgeset's name are the same.
  1625     /// The sections with \@uedgeset head line could be read with this
  1626     /// section reader too.
  1627     virtual bool header(const std::string& line) {
  1628       std::istringstream ls(line);
  1629       std::string command;
  1630       std::string id;
  1631       ls >> command >> id;
  1632       return (command == "@edgeset" || command == "@uedgeset") && name == id;
  1633     }
  1634 
  1635     /// \brief Reader function of the section.
  1636     ///
  1637     /// It reads the content of the section.
  1638     virtual void read(std::istream& is) {
  1639       if (!nodeLabelReader->isLabelReader()) {
  1640 	throw DataFormatError("Cannot find nodeset or label map");
  1641       }
  1642       std::vector<_reader_bits::MapReaderBase<Edge>* > index;
  1643       std::string line;
  1644 
  1645       {
  1646         getline(is, line);
  1647         std::istringstream ls(line);	
  1648         std::string id;
  1649         while (ls >> id) {
  1650           typename MapReaders::iterator it = readers.find(id);
  1651           if (it != readers.end()) {
  1652             index.push_back(it->second);
  1653             it->second->touch();
  1654           } else {
  1655             index.push_back(&skipper);
  1656           }
  1657           if (id == "label") {
  1658             inverter.reset(index.back()->getInverter());
  1659             index.back() = inverter.get();
  1660           }
  1661         }
  1662       }
  1663       for (typename MapReaders::iterator it = readers.begin();
  1664 	   it != readers.end(); ++it) {
  1665 	if (!it->second->touched()) {
  1666 	  ErrorMessage msg;
  1667 	  msg << "Map not found in file: " << it->first;
  1668 	  throw IoParameterError(msg.message());
  1669 	}
  1670       }
  1671       while (getline(is, line)) {	
  1672 	std::istringstream ls(line);
  1673 	Node from = nodeLabelReader->read(ls);
  1674 	Node to = nodeLabelReader->read(ls);
  1675 	Edge edge = graph.addEdge(from, to);
  1676 	for (int i = 0; i < int(index.size()); ++i) {
  1677 	  index[i]->read(ls, edge);
  1678 	}
  1679       }
  1680     }
  1681 
  1682     virtual void missing() {
  1683       if (readers.empty()) return;
  1684       ErrorMessage msg;
  1685       msg << "EdgeSet section not found in file: @edgeset " << name;
  1686       throw IoParameterError(msg.message());
  1687     }
  1688 
  1689   public:
  1690 
  1691     /// \brief Returns true if the edgeset can give back the edge by its label.
  1692     ///
  1693     /// Returns true if the edgeset can give back the edge by its label.
  1694     /// It is possible only if an "label" named map was read.
  1695     bool isLabelReader() const {
  1696       return inverter.get() != 0;
  1697     }
  1698 
  1699     /// \brief Gives back the edge by its label.
  1700     ///
  1701     /// It reads an id from the stream and gives back which edge belongs to
  1702     /// it. It is possible only if there was read an "label" named map.
  1703     void readLabel(std::istream& is, Edge& edge) const {
  1704       edge = inverter->read(is);
  1705     } 
  1706 
  1707   private:
  1708 
  1709     typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> 
  1710     MapReaders;
  1711     
  1712     MapReaders readers;
  1713    
  1714     Graph& graph;   
  1715     std::string name;
  1716     _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
  1717 
  1718     std::auto_ptr<_reader_bits::MapInverterBase<Edge> > inverter;
  1719     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
  1720   };
  1721 
  1722   /// \ingroup section_io
  1723   /// \brief SectionReader for reading a undirected graph's edgeset.
  1724   ///
  1725   /// The lemon format can store multiple undirected edgesets with several 
  1726   /// maps. The undirected edgeset section's header line is \c \@uedgeset 
  1727   /// \c uedgeset_name, but the \c uedgeset_name may be empty.
  1728   ///
  1729   /// The first line of the section contains the names of the maps separated
  1730   /// with white spaces. Each next lines describes an edge in the edgeset. The
  1731   /// line contains the connected nodes' id and the mapped values for each map.
  1732   ///
  1733   /// The section can handle the directed as a syntactical sugar. Two
  1734   /// undirected edge map describes one directed edge map. This two maps
  1735   /// are the forward map and the backward map and the names of this map
  1736   /// is near the same just with a prefix \c '+' or \c '-' character 
  1737   /// difference.
  1738   ///
  1739   /// If the edgeset contains an \c "label" named map then it will be regarded
  1740   /// as id map. This map should contain only unique values and when the 
  1741   /// \c readLabel() member will read a value from the given stream it will
  1742   /// give back that uicted edge which is mapped to this value.
  1743   ///
  1744   /// The undirected edgeset reader needs a node id reader to identify which 
  1745   /// nodes have to be connected. If a NodeSetReader reads an "label" named 
  1746   /// map, it will be able to resolve the nodes by ids.
  1747   ///
  1748   /// \relates LemonReader
  1749   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  1750   class UEdgeSetReader : public LemonReader::SectionReader {
  1751     typedef LemonReader::SectionReader Parent;
  1752   public:
  1753 
  1754     typedef _Graph Graph;
  1755     typedef _Traits Traits;
  1756     typedef typename Graph::Node Node;
  1757     typedef typename Graph::Edge Edge;
  1758     typedef typename Graph::UEdge UEdge;
  1759     typedef typename Traits::Skipper DefaultSkipper;
  1760 
  1761     /// \brief Constructor.
  1762     ///
  1763     /// Constructor for UEdgeSetReader. It creates the UEdgeSetReader 
  1764     /// and attach it into the given LemonReader. The undirected edgeset 
  1765     /// reader will add the read undirected edges to the given Graph. It 
  1766     /// will use the given node id reader to read the source and target 
  1767     /// nodes of the edges. The reader will read the section only if the 
  1768     /// \c _name and the \c uedgset_name are the same. 
  1769     template <typename NodeLabelReader>
  1770     UEdgeSetReader(LemonReader& _reader, 
  1771 		       Graph& _graph, 
  1772 		       const NodeLabelReader& _nodeLabelReader, 
  1773 		       const std::string& _name = std::string(),
  1774 		       const DefaultSkipper& _skipper = DefaultSkipper()) 
  1775       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
  1776       checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
  1777       nodeLabelReader.reset(new _reader_bits::
  1778 			 LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
  1779     }
  1780     /// \brief Destructor.
  1781     ///
  1782     /// Destructor for UEdgeSetReader.
  1783     virtual ~UEdgeSetReader() {
  1784       for (typename MapReaders::iterator it = readers.begin(); 
  1785 	   it != readers.end(); ++it) {
  1786 	delete it->second;
  1787       }
  1788     }
  1789 
  1790   private:
  1791     UEdgeSetReader(const UEdgeSetReader&);
  1792     void operator=(const UEdgeSetReader&);
  1793 
  1794   public:
  1795 
  1796     /// \brief Add a new undirected edge map reader command for the reader.
  1797     ///
  1798     /// Add a new edge undirected map reader command for the reader.
  1799     template <typename Map>
  1800     UEdgeSetReader& readUEdgeMap(std::string label, Map& map) {
  1801       return _readMap<
  1802 	typename Traits::template Reader<typename Map::Value>, Map, 
  1803 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1804     }
  1805 
  1806     template <typename Map>
  1807     UEdgeSetReader& readUEdgeMap(std::string label, const Map& map) {
  1808       return _readMap<
  1809 	typename Traits::template Reader<typename Map::Value>, Map, 
  1810 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1811     }
  1812 
  1813     /// \brief Add a new undirected edge map reader command for the reader.
  1814     ///
  1815     /// Add a new edge undirected map reader command for the reader.
  1816     template <typename ItemReader, typename Map>
  1817     UEdgeSetReader& readUEdgeMap(std::string label, Map& map, 
  1818                                  const ItemReader& ir = ItemReader()) {
  1819       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  1820 	(label, map, ir);
  1821     }
  1822 
  1823     template <typename ItemReader, typename Map>
  1824     UEdgeSetReader& readUEdgeMap(std::string label, const Map& map, 
  1825                                  const ItemReader& ir = ItemReader()) {
  1826       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type >
  1827 	(label, map, ir);
  1828     }
  1829 
  1830   private:
  1831 
  1832     template <typename ItemReader, typename Map, typename MapParameter>
  1833     UEdgeSetReader& _readMap(std::string label, MapParameter map,
  1834                              const ItemReader& ir = ItemReader()) {
  1835       checkConcept<concepts::WriteMap<UEdge, typename Map::Value>, Map>();
  1836       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  1837       if (readers.find(label) != readers.end()) {
  1838 	ErrorMessage msg;
  1839 	msg << "Multiple read rule for edge map: " << label;
  1840 	throw IoParameterError(msg.message());
  1841       }
  1842       readers.insert(
  1843 	make_pair(label, new _reader_bits::
  1844 		  MapReader<UEdge, Map, ItemReader>(map, ir)));
  1845       return *this;
  1846     }
  1847 
  1848   public:
  1849 
  1850     /// \brief Add a new undirected edge map skipper command for the reader.
  1851     ///
  1852     /// Add a new undirected edge map skipper command for the reader.
  1853     template <typename ItemReader>
  1854     UEdgeSetReader& skipUEdgeMap(std::string label, 
  1855                                  const ItemReader& ir = ItemReader()) {
  1856       if (readers.find(label) != readers.end()) {
  1857 	ErrorMessage msg;
  1858 	msg << "Multiple read rule for node map: " << label;
  1859 	throw IoParameterError(msg.message());
  1860       }
  1861       readers.insert(make_pair(label, new _reader_bits::
  1862 			       SkipReader<UEdge, ItemReader>(ir)));
  1863       return *this;
  1864     }
  1865 
  1866     /// \brief Add a new directed edge map reader command for the reader.
  1867     ///
  1868     /// Add a new directed edge map reader command for the reader.
  1869     template <typename Map>
  1870     UEdgeSetReader& readEdgeMap(std::string label, Map& map) {
  1871       return _readDirMap<
  1872 	typename Traits::template Reader<typename Map::Value>, Map,
  1873 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1874     }
  1875 
  1876     template <typename Map>
  1877     UEdgeSetReader& readEdgeMap(std::string label, const Map& map) {
  1878       return _readDirMap<
  1879 	typename Traits::template Reader<typename Map::Value>, Map,
  1880 	typename _reader_bits::Arg<Map>::Type>(label, map);
  1881     }
  1882 
  1883     /// \brief Add a new directed edge map reader command for the reader.
  1884     ///
  1885     /// Add a new directed edge map reader command for the reader.
  1886     template <typename ItemReader, typename Map>
  1887     UEdgeSetReader& readEdgeMap(std::string label, Map& map, 
  1888 				    const ItemReader& ir = ItemReader()) {
  1889       return _readDirMap<ItemReader, Map, 
  1890         typename _reader_bits::Arg<Map>::Type>(label, map, ir);
  1891     }
  1892 
  1893     template <typename ItemReader, typename Map>
  1894     UEdgeSetReader& readEdgeMap(std::string label, const Map& map, 
  1895 				    const ItemReader& ir = ItemReader()) {
  1896       return _readDirMap<ItemReader, Map, 
  1897         typename _reader_bits::Arg<Map>::Type>(label, map, ir);
  1898     }
  1899 
  1900   private:
  1901 
  1902     template <typename ItemReader, typename Map, typename MapParameter>
  1903     UEdgeSetReader& _readDirMap(std::string label, MapParameter map,
  1904 				    const ItemReader& ir = ItemReader()) { 
  1905       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  1906       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
  1907       readUEdgeMap("+" + label, 
  1908                    _reader_bits::forwardComposeMap(graph, map), ir);
  1909       readUEdgeMap("-" + label, 
  1910                    _reader_bits::backwardComposeMap(graph, map), ir);
  1911       return *this;      
  1912     }
  1913 
  1914   public:
  1915 
  1916     /// \brief Add a new directed edge map skipper command for the reader.
  1917     ///
  1918     /// Add a new directed edge map skipper command for the reader.
  1919     template <typename ItemReader>
  1920     UEdgeSetReader& skipEdgeMap(std::string label, 
  1921                                 const ItemReader& ir = ItemReader()) {
  1922       skipUEdgeMap("+" + label, ir);
  1923       skipUEdgeMap("-" + label, ir);
  1924       return *this;
  1925     }
  1926 
  1927   protected:
  1928 
  1929     /// \brief Gives back true when the SectionReader can process 
  1930     /// the section with the given header line.
  1931     ///
  1932     /// It gives back true when the header line starts with \c \@uedgeset,
  1933     /// and the header line's name and the edgeset's name are the same.
  1934     /// The sections with \@edgeset head line could be read with this
  1935     /// section reader too.
  1936     virtual bool header(const std::string& line) {
  1937       std::istringstream ls(line);
  1938       std::string command;
  1939       std::string id;
  1940       ls >> command >> id;
  1941       return (command == "@edgeset" || command == "@uedgeset") && name == id;
  1942     }
  1943 
  1944     /// \brief Reader function of the section.
  1945     ///
  1946     /// It reads the content of the section.
  1947     virtual void read(std::istream& is) {
  1948       if (!nodeLabelReader->isLabelReader()) {
  1949 	throw DataFormatError("Cannot find nodeset or label map");
  1950       }
  1951       std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
  1952       std::string line;
  1953 
  1954       {
  1955         getline(is, line);
  1956         std::istringstream ls(line);	
  1957         std::string id;
  1958         while (ls >> id) {
  1959           typename MapReaders::iterator it = readers.find(id);
  1960           if (it != readers.end()) {
  1961             index.push_back(it->second);
  1962             it->second->touch();
  1963           } else {
  1964             index.push_back(&skipper);
  1965           }
  1966           if (id == "label") {
  1967             inverter.reset(index.back()->getInverter());
  1968             index.back() = inverter.get();
  1969           }
  1970         }
  1971         for (typename MapReaders::iterator it = readers.begin();
  1972              it != readers.end(); ++it) {
  1973           if (!it->second->touched()) {
  1974             ErrorMessage msg;
  1975             msg << "Map not found in file: " << it->first;
  1976             throw IoParameterError(msg.message());
  1977           }
  1978         }
  1979       }
  1980       while (getline(is, line)) {	
  1981 	std::istringstream ls(line);
  1982 	Node from = nodeLabelReader->read(ls);
  1983 	Node to = nodeLabelReader->read(ls);
  1984 	UEdge edge = graph.addEdge(from, to);
  1985 	for (int i = 0; i < int(index.size()); ++i) {
  1986 	  index[i]->read(ls, edge);
  1987 	}
  1988       }
  1989     }
  1990 
  1991     virtual void missing() {
  1992       if (readers.empty()) return;
  1993       ErrorMessage msg;
  1994       msg << "UEdgeSet section not found in file: @uedgeset " << name;
  1995       throw IoParameterError(msg.message());
  1996     }
  1997 
  1998   public:
  1999 
  2000     /// \brief Returns true if the edgeset can give back the edge by its label.
  2001     ///
  2002     /// Returns true if the edgeset can give back the undirected edge by its 
  2003     /// id. It is possible only if an "label" named map was read.
  2004     bool isLabelReader() const {
  2005       return inverter.get() != 0;
  2006     }
  2007 
  2008     /// \brief Gives back the undirected edge by its label.
  2009     ///
  2010     /// It reads an id from the stream and gives back which undirected edge 
  2011     /// belongs to it. It is possible only if there was read an "label" named map.
  2012     void readLabel(std::istream& is, UEdge& uedge) const {
  2013       uedge = inverter->read(is);
  2014     } 
  2015 
  2016     /// \brief Gives back the directed edge by its label.
  2017     ///
  2018     /// It reads an id from the stream and gives back which directed edge 
  2019     /// belongs to it. The directed edge id is the \c '+' or \c '-' character
  2020     /// and the undirected edge id. It is possible only if there was read 
  2021     /// an "label" named map.
  2022     void readLabel(std::istream& is, Edge& edge) const {
  2023       char c;
  2024       is >> c;
  2025       UEdge uedge = inverter->read(is);
  2026       if (c == '+') {
  2027 	edge = graph.direct(uedge, true);
  2028       } else if (c == '-') {
  2029         edge = graph.direct(uedge, false);
  2030       } else {
  2031 	throw DataFormatError("Wrong id format for edge "
  2032 			      "in undirected edgeset");
  2033       }
  2034     } 
  2035 
  2036   private:
  2037 
  2038     typedef std::map<std::string, 
  2039 		     _reader_bits::MapReaderBase<UEdge>*> MapReaders;
  2040     MapReaders readers;
  2041    
  2042     Graph& graph;   
  2043     std::string name;
  2044     _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
  2045 
  2046     std::auto_ptr<_reader_bits::MapInverterBase<UEdge> > inverter;
  2047     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
  2048   };
  2049 
  2050   /// \ingroup section_io
  2051   /// \brief SectionReader for reading labeled nodes.
  2052   ///
  2053   /// The nodes section's header line is \c \@nodes \c nodes_name, but the
  2054   /// \c nodes_name may be empty.
  2055   ///
  2056   /// Each line in the section contains the name of the node 
  2057   /// and then the node id. 
  2058   ///
  2059   /// \relates LemonReader
  2060   template <typename _Graph>
  2061   class NodeReader : public LemonReader::SectionReader {
  2062     typedef LemonReader::SectionReader Parent;
  2063     typedef _Graph Graph;
  2064     typedef typename Graph::Node Node;
  2065   public:
  2066     
  2067     /// \brief Constructor.
  2068     ///
  2069     /// Constructor for NodeReader. It creates the NodeReader and
  2070     /// attach it into the given LemonReader. It will use the given
  2071     /// node id reader to give back the nodes. The reader will read the 
  2072     /// section only if the \c _name and the \c nodes_name are the same. 
  2073     template <typename _LabelReader>
  2074     NodeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  2075 	       const std::string& _name = std::string()) 
  2076       : Parent(_reader), name(_name) {
  2077       checkConcept<_reader_bits::ItemLabelReader<Node>, _LabelReader>();
  2078       nodeLabelReader.reset(new _reader_bits::
  2079 			 LabelReader<Node, _LabelReader>(_labelReader));
  2080     }
  2081 
  2082     /// \brief Destructor.
  2083     ///
  2084     /// Destructor for NodeReader.
  2085     virtual ~NodeReader() {}
  2086 
  2087   private:
  2088     NodeReader(const NodeReader&);
  2089     void operator=(const NodeReader&);
  2090 
  2091   public:
  2092 
  2093     /// \brief Add a node reader command for the NodeReader.
  2094     ///
  2095     /// Add a node reader command for the NodeReader.
  2096     void readNode(std::string label, Node& item) {
  2097       if (readers.find(label) != readers.end()) {
  2098 	ErrorMessage msg;
  2099 	msg << "Multiple read rule for node: " << label;
  2100 	throw IoParameterError(msg.message());
  2101       }
  2102       readers.insert(make_pair(label, _reader_bits::ItemStore<Node>(item)));
  2103     }
  2104 
  2105   protected:
  2106 
  2107     /// \brief Gives back true when the SectionReader can process 
  2108     /// the section with the given header line.
  2109     ///
  2110     /// It gives back true when the header line start with \c \@nodes,
  2111     /// and the header line's name and the reader's name are the same.
  2112     virtual bool header(const std::string& line) {
  2113       std::istringstream ls(line);
  2114       std::string command;
  2115       std::string id;
  2116       ls >> command >> id;
  2117       return command == "@nodes" && name == id;
  2118     }
  2119 
  2120     /// \brief Reader function of the section.
  2121     ///
  2122     /// It reads the content of the section.
  2123     virtual void read(std::istream& is) {
  2124       if (!nodeLabelReader->isLabelReader()) {
  2125 	throw DataFormatError("Cannot find nodeset or label map");
  2126       }
  2127       std::string line;
  2128       while (getline(is, line)) {
  2129 	std::istringstream ls(line);
  2130 	std::string id;
  2131 	ls >> id;
  2132 	typename NodeReaders::iterator it = readers.find(id);
  2133 	if (it != readers.end()) {
  2134 	  it->second.read(nodeLabelReader->read(ls));
  2135 	  it->second.touch();
  2136 	}	
  2137       }
  2138       for (typename NodeReaders::iterator it = readers.begin();
  2139 	   it != readers.end(); ++it) {
  2140 	if (!it->second.touched()) {
  2141 	  ErrorMessage msg;
  2142 	  msg << "Node not found in file: " << it->first;
  2143 	  throw IoParameterError(msg.message());
  2144 	}
  2145       }
  2146     }
  2147 
  2148     virtual void missing() {
  2149       if (readers.empty()) return;
  2150       ErrorMessage msg;
  2151       msg << "Nodes section not found in file: @nodes " << name;
  2152       throw IoParameterError(msg.message());
  2153     }
  2154     
  2155   private:
  2156 
  2157     std::string name;
  2158 
  2159     typedef std::map<std::string, _reader_bits::ItemStore<Node> > NodeReaders;
  2160     NodeReaders readers;
  2161     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
  2162   };
  2163 
  2164   /// \ingroup section_io
  2165   /// \brief SectionReader for reading labeled edges.
  2166   ///
  2167   /// The edges section's header line is \c \@edges \c edges_name, but the
  2168   /// \c edges_name may be empty.
  2169   ///
  2170   /// Each line in the section contains the name of the edge 
  2171   /// and then the edge id. 
  2172   ///
  2173   /// \relates LemonReader
  2174   template <typename _Graph>
  2175   class EdgeReader : public LemonReader::SectionReader {
  2176     typedef LemonReader::SectionReader Parent;
  2177     typedef _Graph Graph;
  2178     typedef typename Graph::Edge Edge;
  2179   public:
  2180     
  2181     /// \brief Constructor.
  2182     ///
  2183     /// Constructor for EdgeReader. It creates the EdgeReader and
  2184     /// attach it into the given LemonReader. It will use the given
  2185     /// edge id reader to give back the edges. The reader will read the 
  2186     /// section only if the \c _name and the \c edges_name are the same. 
  2187     template <typename _LabelReader>
  2188     EdgeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  2189 	       const std::string& _name = std::string()) 
  2190       : Parent(_reader), name(_name) {
  2191       checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
  2192       edgeLabelReader.reset(new _reader_bits::
  2193 			 LabelReader<Edge, _LabelReader>(_labelReader));
  2194     }
  2195 
  2196     /// \brief Destructor.
  2197     ///
  2198     /// Destructor for EdgeReader.
  2199     virtual ~EdgeReader() {}
  2200   private:
  2201     EdgeReader(const EdgeReader&);
  2202     void operator=(const EdgeReader&);
  2203 
  2204   public:
  2205 
  2206     /// \brief Add an edge reader command for the EdgeReader.
  2207     ///
  2208     /// Add an edge reader command for the EdgeReader.
  2209     void readEdge(std::string label, Edge& item) {
  2210       if (readers.find(label) != readers.end()) {
  2211 	ErrorMessage msg;
  2212 	msg << "Multiple read rule for edge: " << label;
  2213 	throw IoParameterError(msg.message());
  2214       }
  2215       readers.insert(make_pair(label, _reader_bits::ItemStore<Edge>(item)));
  2216     }
  2217 
  2218   protected:
  2219 
  2220     /// \brief Gives back true when the SectionReader can process 
  2221     /// the section with the given header line.
  2222     ///
  2223     /// It gives back true when the header line start with \c \@edges,
  2224     /// and the header line's name and the reader's name are the same.
  2225     virtual bool header(const std::string& line) {
  2226       std::istringstream ls(line);
  2227       std::string command;
  2228       std::string id;
  2229       ls >> command >> id;
  2230       return command == "@edges" && name == id;
  2231     }
  2232 
  2233     /// \brief Reader function of the section.
  2234     ///
  2235     /// It reads the content of the section.
  2236     virtual void read(std::istream& is) {
  2237       if (!edgeLabelReader->isLabelReader()) {
  2238 	throw DataFormatError("Cannot find edgeset or label map");
  2239       }
  2240       std::string line;
  2241       while (getline(is, line)) {
  2242 	std::istringstream ls(line);
  2243 	std::string id;
  2244 	ls >> id;
  2245 	typename EdgeReaders::iterator it = readers.find(id);
  2246 	if (it != readers.end()) {
  2247 	  it->second.read(edgeLabelReader->read(ls));
  2248 	  it->second.touch();
  2249 	}	
  2250       }
  2251       for (typename EdgeReaders::iterator it = readers.begin();
  2252 	   it != readers.end(); ++it) {
  2253 	if (!it->second.touched()) {
  2254 	  ErrorMessage msg;
  2255 	  msg << "Edge not found in file: " << it->first;
  2256 	  throw IoParameterError(msg.message());
  2257 	}
  2258       }
  2259     }
  2260 
  2261     virtual void missing() {
  2262       if (readers.empty()) return;
  2263       ErrorMessage msg;
  2264       msg << "Edges section not found in file: @edges " << name;
  2265       throw IoParameterError(msg.message());
  2266     }
  2267     
  2268   private:
  2269 
  2270     std::string name;
  2271 
  2272     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  2273     EdgeReaders readers;
  2274     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
  2275   };
  2276 
  2277   /// \ingroup section_io
  2278   /// \brief SectionReader for reading labeled undirected edges.
  2279   ///
  2280   /// The undirected edges section's header line is \c \@uedges 
  2281   /// \c uedges_name, but the \c uedges_name may be empty.
  2282   ///
  2283   /// Each line in the section contains the name of the undirected edge 
  2284   /// and then the undirected edge id. 
  2285   ///
  2286   /// \relates LemonReader
  2287   template <typename _Graph>
  2288   class UEdgeReader : public LemonReader::SectionReader {
  2289     typedef LemonReader::SectionReader Parent;
  2290     typedef _Graph Graph;
  2291     typedef typename Graph::Edge Edge;
  2292     typedef typename Graph::UEdge UEdge;
  2293   public:
  2294     
  2295     /// \brief Constructor.
  2296     ///
  2297     /// Constructor for UEdgeReader. It creates the UEdgeReader and
  2298     /// attach it into the given LemonReader. It will use the given
  2299     /// undirected edge id reader to give back the edges. The reader will 
  2300     /// read the section only if the \c _name and the \c uedges_name are 
  2301     /// the same. 
  2302     template <typename _LabelReader>
  2303     UEdgeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  2304 	       const std::string& _name = std::string()) 
  2305       : Parent(_reader), name(_name) {
  2306       checkConcept<_reader_bits::ItemLabelReader<UEdge>, _LabelReader>();
  2307       checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
  2308       uedgeLabelReader.reset(new _reader_bits::
  2309 			     LabelReader<UEdge, _LabelReader>(_labelReader));
  2310       edgeLabelReader.reset(new _reader_bits::
  2311 			    LabelReader<Edge, _LabelReader>(_labelReader));
  2312     }
  2313 
  2314     /// \brief Destructor.
  2315     ///
  2316     /// Destructor for UEdgeReader.
  2317     virtual ~UEdgeReader() {}
  2318   private:
  2319     UEdgeReader(const UEdgeReader&);
  2320     void operator=(const UEdgeReader&);
  2321 
  2322   public:
  2323 
  2324     /// \brief Add an undirected edge reader command for the UEdgeReader.
  2325     ///
  2326     /// Add an undirected edge reader command for the UEdgeReader.
  2327     void readUEdge(std::string label, UEdge& item) {
  2328       if (uedgeReaders.find(label) != uedgeReaders.end()) {
  2329 	ErrorMessage msg;
  2330 	msg << "Multiple read rule for undirected edge: " << label;
  2331 	throw IoParameterError(msg.message());
  2332       }
  2333       uedgeReaders.insert(make_pair(label, _reader_bits::
  2334 					ItemStore<UEdge>(item)));
  2335     }
  2336 
  2337     /// \brief Add an edge reader command for the UEdgeReader.
  2338     ///
  2339     /// Add an edge reader command for the UEdgeReader.
  2340     void readEdge(std::string label, Edge& item) {
  2341       if (edgeReaders.find(label) != edgeReaders.end()) {
  2342 	ErrorMessage msg;
  2343 	msg << "Multiple read rule for edge: " << label;
  2344 	throw IoParameterError(msg.message());
  2345       }
  2346       edgeReaders.insert(make_pair(label, _reader_bits::ItemStore<Edge>(item)));
  2347     }
  2348 
  2349   protected:
  2350 
  2351     /// \brief Gives back true when the SectionReader can process 
  2352     /// the section with the given header line.
  2353     ///
  2354     /// It gives back true when the header line start with \c \@edges,
  2355     /// and the header line's name and the reader's name are the same.
  2356     virtual bool header(const std::string& line) {
  2357       std::istringstream ls(line);
  2358       std::string command;
  2359       std::string id;
  2360       ls >> command >> id;
  2361       return command == "@uedges" && name == id;
  2362     }
  2363 
  2364     /// \brief Reader function of the section.
  2365     ///
  2366     /// It reads the content of the section.
  2367     virtual void read(std::istream& is) {
  2368       if (!edgeLabelReader->isLabelReader()) {
  2369 	throw DataFormatError("Cannot find undirected edgeset or label map");
  2370       }
  2371       if (!uedgeLabelReader->isLabelReader()) {
  2372 	throw DataFormatError("Cannot find undirected edgeset or label map");
  2373       }
  2374       std::string line;
  2375       while (getline(is, line)) {
  2376 	std::istringstream ls(line);
  2377 	std::string id;
  2378 	ls >> id;
  2379 	{
  2380 	  typename UEdgeReaders::iterator it = uedgeReaders.find(id);
  2381 	  if (it != uedgeReaders.end()) {
  2382 	    it->second.read(uedgeLabelReader->read(ls));
  2383 	    it->second.touch();
  2384 	    continue;
  2385 	  }	
  2386 	} {
  2387 	  typename EdgeReaders::iterator it = edgeReaders.find(id);
  2388 	  if (it != edgeReaders.end()) {
  2389 	    it->second.read(edgeLabelReader->read(ls));
  2390 	    it->second.touch();
  2391 	    continue;
  2392 	  }	
  2393 	}
  2394       }
  2395       for (typename EdgeReaders::iterator it = edgeReaders.begin();
  2396 	   it != edgeReaders.end(); ++it) {
  2397 	if (!it->second.touched()) {
  2398 	  ErrorMessage msg;
  2399 	  msg << "Edge not found in file: " << it->first;
  2400 	  throw IoParameterError(msg.message());
  2401 	}
  2402       }
  2403       for (typename UEdgeReaders::iterator it = uedgeReaders.begin();
  2404 	   it != uedgeReaders.end(); ++it) {
  2405 	if (!it->second.touched()) {
  2406 	  ErrorMessage msg;
  2407 	  msg << "UEdge not found in file: " << it->first;
  2408 	  throw IoParameterError(msg.message());
  2409 	}
  2410       }
  2411     }
  2412 
  2413     virtual void missing() {
  2414       if (edgeReaders.empty() && uedgeReaders.empty()) return;
  2415       ErrorMessage msg;
  2416       msg << "UEdges section not found in file: @uedges " << name;
  2417       throw IoParameterError(msg.message());
  2418     }
  2419     
  2420   private:
  2421 
  2422     std::string name;
  2423 
  2424     typedef std::map<std::string, 
  2425 		     _reader_bits::ItemStore<UEdge> > UEdgeReaders;
  2426     UEdgeReaders uedgeReaders;
  2427     std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uedgeLabelReader;
  2428 
  2429     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  2430     EdgeReaders edgeReaders;
  2431     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
  2432   };
  2433 
  2434   /// \ingroup section_io
  2435   /// \brief SectionReader for attributes.
  2436   ///
  2437   /// The lemon format can store multiple attribute set. Each set has
  2438   /// the header line \c \@attributes \c attributeset_name, but the 
  2439   /// attributeset_name may be empty.
  2440   ///
  2441   /// The attributeset section contains several lines. Each of them starts
  2442   /// with an attribute and then a the value for the id.
  2443   ///
  2444   /// \relates LemonReader
  2445   template <typename _Traits = DefaultReaderTraits>
  2446   class AttributeReader : public LemonReader::SectionReader {
  2447     typedef LemonReader::SectionReader Parent;
  2448     typedef _Traits Traits; 
  2449   public:
  2450     /// \brief Constructor.
  2451     ///
  2452     /// Constructor for AttributeReader. It creates the AttributeReader and
  2453     /// attach it into the given LemonReader. The reader process a section
  2454     /// only if the \c section_name and the \c _name are the same.
  2455     AttributeReader(LemonReader& _reader, 
  2456 		    const std::string& _name = std::string()) 
  2457       : Parent(_reader), name(_name) {}
  2458 
  2459     /// \brief Destructor.
  2460     ///
  2461     /// Destructor for AttributeReader.
  2462     virtual ~AttributeReader() {
  2463       for (typename Readers::iterator it = readers.begin(); 
  2464 	   it != readers.end(); ++it) {
  2465 	delete it->second;
  2466       }
  2467     }
  2468 
  2469   private:
  2470     AttributeReader(const AttributeReader&);
  2471     void operator=(AttributeReader&);
  2472 
  2473   public:
  2474     /// \brief Add an attribute reader command for the reader.
  2475     ///
  2476     /// Add an attribute reader command for the reader.
  2477     template <typename Value>
  2478     AttributeReader& readAttribute(const std::string& label, Value& value) {
  2479       return readAttribute<typename Traits::template Reader<Value> >
  2480 	(label, value);
  2481     }
  2482 
  2483     /// \brief Add an attribute reader command for the reader.
  2484     ///
  2485     /// Add an attribute reader command for the reader.
  2486     template <typename ItemReader, typename Value>
  2487     AttributeReader& readAttribute(const std::string& label, Value& value,
  2488 				   const ItemReader& ir = ItemReader()) {
  2489       checkConcept<_reader_bits::ItemReader<Value>, ItemReader>();
  2490       if (readers.find(label) != readers.end()) {
  2491 	ErrorMessage msg;
  2492 	msg << "Multiple read rule for attribute: " << label;
  2493 	throw IoParameterError(msg.message());
  2494       }
  2495       readers.insert(make_pair(label, new _reader_bits::
  2496 			       ValueReader<Value, ItemReader>(value, ir)));
  2497       return *this;
  2498     }
  2499 
  2500   protected:
  2501 
  2502     /// \brief Gives back true when the SectionReader can process 
  2503     /// the section with the given header line.
  2504     ///
  2505     /// It gives back true when the header line start with \c \@attributes,
  2506     /// and the header line's id and the attributeset's id are the same.
  2507     bool header(const std::string& line) {
  2508       std::istringstream ls(line);
  2509       std::string command;
  2510       std::string id;
  2511       ls >> command >> id;
  2512       return command == "@attributes" && name == id;
  2513     }
  2514 
  2515     /// \brief Reader function of the section.
  2516     ///
  2517     /// It reads the content of the section.
  2518     void read(std::istream& is) {
  2519       std::string line;
  2520       while (getline(is, line)) {
  2521 	std::istringstream ls(line);
  2522 	std::string id;
  2523 	ls >> id;
  2524 	typename Readers::iterator it = readers.find(id);
  2525 	if (it != readers.end()) {
  2526 	  it->second->read(ls);
  2527  	  it->second->touch();
  2528 	}
  2529       }
  2530       for (typename Readers::iterator it = readers.begin();
  2531 	   it != readers.end(); ++it) {
  2532 	if (!it->second->touched()) {
  2533 	  ErrorMessage msg;
  2534 	  msg << "Attribute not found in file: " << it->first;
  2535 	  throw IoParameterError(msg.message());
  2536 	}	
  2537       }
  2538     }    
  2539     
  2540     virtual void missing() {
  2541       if (readers.empty()) return;
  2542       ErrorMessage msg;
  2543       msg << "Attribute section not found in file: @attributes " << name;
  2544       throw IoParameterError(msg.message());
  2545     }
  2546 
  2547   private:
  2548     std::string name;
  2549 
  2550     typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers;
  2551     Readers readers;  
  2552   };
  2553 
  2554   /// \ingroup section_io
  2555   /// \brief SectionReader for reading extra node maps.
  2556   ///
  2557   /// The lemon format can store maps in the nodeset sections. This
  2558   /// class let you make distinict section to store maps.  The main
  2559   /// purpose of this class is a logical separation of some maps. The
  2560   /// other useful application could be to store paths in node maps.
  2561   ///
  2562   /// The first line of the section contains the names of the maps
  2563   /// separated with white spaces. Each next line describes an item
  2564   /// in the itemset, and contains in the first column the label of
  2565   /// the item and then the mapped values for each map.
  2566   ///
  2567   /// \relates LemonReader
  2568   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  2569   class NodeMapReader : public LemonReader::SectionReader {
  2570     typedef LemonReader::SectionReader Parent;
  2571   public:
  2572 
  2573     typedef _Graph Graph;
  2574     typedef typename Graph::Node Node;
  2575     typedef _Traits Traits;
  2576     typedef typename Traits::Skipper DefaultSkipper;
  2577 
  2578     /// \brief Constructor.
  2579     ///
  2580     /// Constructor for NodeMapReader. It creates the NodeMapReader and
  2581     /// attach it into the given LemonReader. The reader will read
  2582     /// the section when the \c section_name and the \c _name are the same.
  2583     template <typename _LabelReader>
  2584     NodeMapReader(LemonReader& _reader, 
  2585 		  const Graph& _graph, 
  2586 		  const _LabelReader& _labelReader,
  2587 		  const std::string& _name = std::string(),
  2588 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
  2589       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
  2590       labelReader.reset(new _reader_bits::
  2591 			LabelReader<Node, _LabelReader>(_labelReader));
  2592     } 
  2593 
  2594 
  2595     /// \brief Destructor.
  2596     ///
  2597     /// Destructor for NodeMapReader.
  2598     virtual ~NodeMapReader() {
  2599       for (typename MapReaders::iterator it = readers.begin(); 
  2600 	   it != readers.end(); ++it) {
  2601 	delete it->second;
  2602       }
  2603     }
  2604 
  2605   private:
  2606     NodeMapReader(const NodeMapReader&);
  2607     void operator=(const NodeMapReader&);
  2608   
  2609   public:
  2610 
  2611     /// \brief Add a new node map reader command for the reader.
  2612     ///
  2613     /// Add a new node map reader command for the reader.
  2614     template <typename Map>
  2615     NodeMapReader& readNodeMap(std::string label, Map& map) {
  2616       return _readMap<
  2617 	typename Traits::template Reader<typename Map::Value>, Map,
  2618 	typename _reader_bits::Arg<Map>::Type>(label, map);
  2619     }
  2620 
  2621     template <typename Map>
  2622     NodeMapReader& readNodeMap(std::string label, const Map& map) {
  2623       return _readMap<
  2624 	typename Traits::template Reader<typename Map::Value>, Map,
  2625 	typename _reader_bits::Arg<Map>::Type>(label, map);
  2626     }
  2627 
  2628     /// \brief Add a new node map reader command for the reader.
  2629     ///
  2630     /// Add a new node map reader command for the reader.
  2631     template <typename ItemReader, typename Map>
  2632     NodeMapReader& readNodeMap(std::string label, Map& map, 
  2633 			       const ItemReader& ir = ItemReader()) {
  2634       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  2635 	(label, map, ir);
  2636     }
  2637 
  2638     template <typename ItemReader, typename Map>
  2639     NodeMapReader& readNodeMap(std::string label, const Map& map, 
  2640 			       const ItemReader& ir = ItemReader()) {
  2641       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  2642 	(label, map, ir);
  2643     }
  2644 
  2645   private:
  2646 
  2647     template <typename ItemReader, typename Map, typename MapParameter>
  2648     NodeMapReader& _readMap(std::string label, MapParameter map, 
  2649 			   const ItemReader& ir = ItemReader()) {
  2650       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
  2651       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  2652       if (readers.find(label) != readers.end()) {
  2653 	ErrorMessage msg;
  2654 	msg << "Multiple read rule for map: " << label;
  2655 	throw IoParameterError(msg.message());
  2656       }      
  2657       readers.insert(
  2658 	make_pair(label, new _reader_bits::
  2659 		  MapReader<Node, Map, ItemReader>(map, ir)));
  2660       return *this;
  2661     }
  2662 
  2663   public:
  2664 
  2665     /// \brief Add a new node map skipper command for the reader.
  2666     ///
  2667     /// Add a new node map skipper command for the reader.
  2668     template <typename ItemReader>
  2669     NodeMapReader& skipNodeMap(std::string label, 
  2670 			       const ItemReader& ir = ItemReader()) {
  2671       if (readers.find(label) != readers.end()) {
  2672 	ErrorMessage msg;
  2673 	msg << "Multiple read rule for map: " << label;
  2674 	throw IoParameterError(msg.message());
  2675       }
  2676       readers.insert(make_pair(label, new _reader_bits::
  2677 			       SkipReader<Node, ItemReader>(ir)));
  2678       return *this;
  2679     }
  2680 
  2681   protected:
  2682 
  2683     /// \brief Gives back true when the SectionReader can process 
  2684     /// the section with the given header line.
  2685     ///
  2686     /// It gives back true when the header line starts with \c \@mapset,
  2687     /// and the header line's name and the mapset's name are the same.
  2688     virtual bool header(const std::string& line) {
  2689       std::istringstream ls(line);
  2690       std::string command;
  2691       std::string id;
  2692       ls >> command >> id;
  2693       return command == "@nodemaps" && name == id;
  2694     }
  2695 
  2696     /// \brief Reader function of the section.
  2697     ///
  2698     /// It reads the content of the section.
  2699     virtual void read(std::istream& is) {
  2700       std::vector<_reader_bits::MapReaderBase<Node>* > index;
  2701       std::string line;
  2702 
  2703       {
  2704         getline(is, line);
  2705         std::istringstream ls(line);
  2706         std::string id;
  2707         while (ls >> id) {
  2708           typename MapReaders::iterator it = readers.find(id);
  2709           if (it != readers.end()) {
  2710             it->second->touch();
  2711             index.push_back(it->second);
  2712           } else {
  2713             index.push_back(&skipper);
  2714           }
  2715         }
  2716       }
  2717       for (typename MapReaders::iterator it = readers.begin();
  2718 	   it != readers.end(); ++it) {
  2719 	if (!it->second->touched()) {
  2720 	  ErrorMessage msg;
  2721 	  msg << "Map not found in file: " << it->first;
  2722 	  throw IoParameterError(msg.message());
  2723 	}
  2724       }
  2725       while (getline(is, line)) {	
  2726 	std::istringstream ls(line);
  2727 	Node node = labelReader->read(ls);
  2728 	for (int i = 0; i < int(index.size()); ++i) {
  2729 	  index[i]->read(ls, node);
  2730 	}
  2731       }
  2732     }
  2733 
  2734     virtual void missing() {
  2735       if (readers.empty()) return;
  2736       ErrorMessage msg;
  2737       msg << "NodeMap section not found in file: @nodemaps " << name;
  2738       throw IoParameterError(msg.message());
  2739     }
  2740 
  2741   private:
  2742 
  2743     typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
  2744     MapReaders readers;
  2745    
  2746     const Graph& graph;   
  2747     std::string name;
  2748     _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
  2749     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > labelReader;
  2750 
  2751   };
  2752 
  2753   /// \ingroup section_io
  2754   /// \brief SectionReader for reading extra edge maps.
  2755   ///
  2756   /// The lemon format can store maps in the edgeset sections. This
  2757   /// class let you make distinict section to store maps.  The main
  2758   /// purpose of this class is a logical separation of some maps. The
  2759   /// other useful application could be to store paths in edge maps.
  2760   ///
  2761   /// The first line of the section contains the names of the maps
  2762   /// separated with white spaces. Each next line describes an item
  2763   /// in the itemset, and contains in the first column the label of
  2764   /// the item and then the mapped values for each map.
  2765   ///
  2766   /// \relates LemonReader
  2767   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  2768   class EdgeMapReader : public LemonReader::SectionReader {
  2769     typedef LemonReader::SectionReader Parent;
  2770   public:
  2771 
  2772     typedef _Graph Graph;
  2773     typedef typename Graph::Edge Edge;
  2774     typedef _Traits Traits;
  2775     typedef typename Traits::Skipper DefaultSkipper;
  2776 
  2777     /// \brief Constructor.
  2778     ///
  2779     /// Constructor for EdgeMapReader. It creates the EdgeMapReader and
  2780     /// attach it into the given LemonReader. The reader will read
  2781     /// the section when the \c section_name and the \c _name are the same.
  2782     template <typename _LabelReader>
  2783     EdgeMapReader(LemonReader& _reader, 
  2784 		   const Graph& _graph, 
  2785 		   const _LabelReader& _labelReader,
  2786 		   const std::string& _name = std::string(),
  2787 		   const DefaultSkipper& _skipper = DefaultSkipper()) 
  2788       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
  2789       labelReader.reset(new _reader_bits::
  2790 			LabelReader<Edge, _LabelReader>(_labelReader));
  2791     } 
  2792 
  2793 
  2794     /// \brief Destructor.
  2795     ///
  2796     /// Destructor for EdgeMapReader.
  2797     virtual ~EdgeMapReader() {
  2798       for (typename MapReaders::iterator it = readers.begin(); 
  2799 	   it != readers.end(); ++it) {
  2800 	delete it->second;
  2801       }
  2802     }
  2803 
  2804   private:
  2805     EdgeMapReader(const EdgeMapReader&);
  2806     void operator=(const EdgeMapReader&);
  2807   
  2808   public:
  2809 
  2810     /// \brief Add a new edge map reader command for the reader.
  2811     ///
  2812     /// Add a new edge map reader command for the reader.
  2813     template <typename Map>
  2814     EdgeMapReader& readEdgeMap(std::string label, Map& map) {
  2815       return _readMap<
  2816 	typename Traits::template Reader<typename Map::Value>, Map,
  2817 	typename _reader_bits::Arg<Map>::Type>(label, map);
  2818     }
  2819 
  2820     template <typename Map>
  2821     EdgeMapReader& readEdgeMap(std::string label, const Map& map) {
  2822       return _readMap<
  2823 	typename Traits::template Reader<typename Map::Value>, Map,
  2824 	typename _reader_bits::Arg<Map>::Type>(label, map);
  2825     }
  2826 
  2827     /// \brief Add a new edge map reader command for the reader.
  2828     ///
  2829     /// Add a new edge map reader command for the reader.
  2830     template <typename ItemReader, typename Map>
  2831     EdgeMapReader& readEdgeMap(std::string label, Map& map, 
  2832 			  const ItemReader& ir = ItemReader()) {
  2833       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  2834 	(label, map, ir);
  2835     }
  2836 
  2837     template <typename ItemReader, typename Map>
  2838     EdgeMapReader& readEdgeMap(std::string label, const Map& map, 
  2839 			  const ItemReader& ir = ItemReader()) {
  2840       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  2841 	(label, map, ir);
  2842     }
  2843 
  2844   private:
  2845 
  2846     template <typename ItemReader, typename Map, typename MapParameter>
  2847     EdgeMapReader& _readMap(std::string label, MapParameter map, 
  2848 				const ItemReader& ir = ItemReader()) {
  2849       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
  2850       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  2851       if (readers.find(label) != readers.end()) {
  2852 	ErrorMessage msg;
  2853 	msg << "Multiple read rule for map: " << label;
  2854 	throw IoParameterError(msg.message());
  2855       }      
  2856       readers.insert(
  2857 	make_pair(label, new _reader_bits::
  2858 		  MapReader<Edge, Map, ItemReader>(map, ir)));
  2859       return *this;
  2860     }
  2861 
  2862   public:
  2863 
  2864     /// \brief Add a new edge map skipper command for the reader.
  2865     ///
  2866     /// Add a new edge map skipper command for the reader.
  2867     template <typename ItemReader>
  2868     EdgeMapReader& skipEdgeMap(std::string label, 
  2869 			  const ItemReader& ir = ItemReader()) {
  2870       if (readers.find(label) != readers.end()) {
  2871 	ErrorMessage msg;
  2872 	msg << "Multiple read rule for map: " << label;
  2873 	throw IoParameterError(msg.message());
  2874       }
  2875       readers.insert(make_pair(label, new _reader_bits::
  2876 			       SkipReader<Edge, ItemReader>(ir)));
  2877       return *this;
  2878     }
  2879 
  2880   protected:
  2881 
  2882     /// \brief Gives back true when the SectionReader can process 
  2883     /// the section with the given header line.
  2884     ///
  2885     /// It gives back true when the header line starts with \c \@mapset,
  2886     /// and the header line's name and the mapset's name are the same.
  2887     virtual bool header(const std::string& line) {
  2888       std::istringstream ls(line);
  2889       std::string command;
  2890       std::string id;
  2891       ls >> command >> id;
  2892       return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
  2893     }
  2894 
  2895     /// \brief Reader function of the section.
  2896     ///
  2897     /// It reads the content of the section.
  2898     virtual void read(std::istream& is) {
  2899       std::vector<_reader_bits::MapReaderBase<Edge>* > index;
  2900       std::string line;
  2901 
  2902       {
  2903         getline(is, line);
  2904         std::istringstream ls(line);
  2905         std::string id;
  2906         while (ls >> id) {
  2907           typename MapReaders::iterator it = readers.find(id);
  2908           if (it != readers.end()) {
  2909             it->second->touch();
  2910             index.push_back(it->second);
  2911           } else {
  2912             index.push_back(&skipper);
  2913           }
  2914         }
  2915       }
  2916       for (typename MapReaders::iterator it = readers.begin();
  2917 	   it != readers.end(); ++it) {
  2918 	if (!it->second->touched()) {
  2919 	  ErrorMessage msg;
  2920 	  msg << "Map not found in file: " << it->first;
  2921 	  throw IoParameterError(msg.message());
  2922 	}
  2923       }
  2924       while (getline(is, line)) {	
  2925 	std::istringstream ls(line);
  2926 	Edge edge = labelReader->read(ls);
  2927 	for (int i = 0; i < int(index.size()); ++i) {
  2928 	  index[i]->read(ls, edge);
  2929 	}
  2930       }
  2931     }
  2932 
  2933     virtual void missing() {
  2934       if (readers.empty()) return;
  2935       ErrorMessage msg;
  2936       msg << "EdgeMap section not found in file: @edgemaps " << name;
  2937       throw IoParameterError(msg.message());
  2938     }
  2939 
  2940   private:
  2941 
  2942     typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
  2943     MapReaders readers;
  2944    
  2945     const Graph& graph;   
  2946     std::string name;
  2947     _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
  2948     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > labelReader;
  2949 
  2950   };
  2951 
  2952   /// \ingroup section_io
  2953   /// \brief SectionReader for reading extra undirected edge maps.
  2954   ///
  2955   /// The lemon format can store maps in the uedgeset sections. This
  2956   /// class let you make distinict section to store maps.  The main
  2957   /// purpose of this class is a logical separation of some maps. The
  2958   /// other useful application could be to store paths in undirected
  2959   /// edge maps.
  2960   ///
  2961   /// The first line of the section contains the names of the maps
  2962   /// separated with white spaces. Each next line describes an item
  2963   /// in the itemset, and contains in the first column the label of
  2964   /// the item and then the mapped values for each map.
  2965   ///
  2966   /// \relates LemonReader
  2967   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  2968   class UEdgeMapReader : public LemonReader::SectionReader {
  2969     typedef LemonReader::SectionReader Parent;
  2970   public:
  2971 
  2972     typedef _Graph Graph;
  2973     typedef typename Graph::Edge Edge;
  2974     typedef typename Graph::UEdge UEdge;
  2975     typedef _Traits Traits;
  2976     typedef typename Traits::Skipper DefaultSkipper;
  2977 
  2978     /// \brief Constructor.
  2979     ///
  2980     /// Constructor for UEdgeMapReader. It creates the UEdgeMapReader and
  2981     /// attach it into the given LemonReader. The reader will read
  2982     /// the section when the \c section_name and the \c _name are the same.
  2983     template <typename _LabelReader>
  2984     UEdgeMapReader(LemonReader& _reader, const Graph& _graph, 
  2985 		   const _LabelReader& _labelReader,
  2986 		   const std::string& _name = std::string(),
  2987 		   const DefaultSkipper& _skipper = DefaultSkipper()) 
  2988       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
  2989       labelReader.reset(new _reader_bits::
  2990 			LabelReader<UEdge, _LabelReader>(_labelReader));
  2991     } 
  2992 
  2993 
  2994     /// \brief Destructor.
  2995     ///
  2996     /// Destructor for UEdgeMapReader.
  2997     virtual ~UEdgeMapReader() {
  2998       for (typename MapReaders::iterator it = readers.begin(); 
  2999 	   it != readers.end(); ++it) {
  3000 	delete it->second;
  3001       }
  3002     }
  3003 
  3004   private:
  3005     UEdgeMapReader(const UEdgeMapReader&);
  3006     void operator=(const UEdgeMapReader&);
  3007   
  3008   public:
  3009 
  3010     /// \brief Add a new undirected edge map reader command for the
  3011     /// reader.
  3012     ///
  3013     /// Add a new undirected edge map reader command for the reader.
  3014     template <typename Map>
  3015     UEdgeMapReader& readUEdgeMap(std::string label, Map& map) {
  3016       return _readMap<
  3017 	typename Traits::template Reader<typename Map::Value>, Map,
  3018 	typename _reader_bits::Arg<Map>::Type>(label, map);
  3019     }
  3020 
  3021     template <typename Map>
  3022     UEdgeMapReader& readUEdgeMap(std::string label, const Map& map) {
  3023       return _readMap<
  3024 	typename Traits::template Reader<typename Map::Value>, Map,
  3025 	typename _reader_bits::Arg<Map>::Type>(label, map);
  3026     }
  3027 
  3028     /// \brief Add a new undirected edge map reader command for the
  3029     /// reader.
  3030     ///
  3031     /// Add a new undirected edge map reader command for the reader.
  3032     template <typename ItemReader, typename Map>
  3033     UEdgeMapReader& readUEdgeMap(std::string label, Map& map, 
  3034 			  const ItemReader& ir = ItemReader()) {
  3035       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  3036 	(label, map, ir);
  3037     }
  3038 
  3039     template <typename ItemReader, typename Map>
  3040     UEdgeMapReader& readUEdgeMap(std::string label, const Map& map, 
  3041 			  const ItemReader& ir = ItemReader()) {
  3042       return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
  3043 	(label, map, ir);
  3044     }
  3045 
  3046   private:
  3047 
  3048     template <typename ItemReader, typename Map, typename MapParameter>
  3049     UEdgeMapReader& _readMap(std::string label, MapParameter map, 
  3050 				const ItemReader& ir = ItemReader()) {
  3051       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
  3052       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  3053       if (readers.find(label) != readers.end()) {
  3054 	ErrorMessage msg;
  3055 	msg << "Multiple read rule for map: " << label;
  3056 	throw IoParameterError(msg.message());
  3057       }      
  3058       readers.insert(
  3059 	make_pair(label, new _reader_bits::
  3060 		  MapReader<UEdge, Map, ItemReader>(map, ir)));
  3061       return *this;
  3062     }
  3063 
  3064   public:
  3065 
  3066     /// \brief Add a new undirected edge map skipper command for the
  3067     /// reader.
  3068     ///
  3069     /// Add a new undirected edge map skipper command for the reader.
  3070     template <typename ItemReader>
  3071     UEdgeMapReader& skipUEdgeMap(std::string label, 
  3072 			  const ItemReader& ir = ItemReader()) {
  3073       if (readers.find(label) != readers.end()) {
  3074 	ErrorMessage msg;
  3075 	msg << "Multiple read rule for map: " << label;
  3076 	throw IoParameterError(msg.message());
  3077       }
  3078       readers.insert(make_pair(label, new _reader_bits::
  3079 			       SkipReader<Edge, ItemReader>(ir)));
  3080       return *this;
  3081     }
  3082 
  3083     /// \brief Add a new directed edge map reader command for the reader.
  3084     ///
  3085     /// Add a new directed edge map reader command for the reader.
  3086     template <typename Map>
  3087     UEdgeMapReader& readEdgeMap(std::string label, Map& map) {
  3088       return _readDirMap<
  3089 	typename Traits::template Reader<typename Map::Value>, Map,
  3090 	typename _reader_bits::Arg<Map>::Type>(label, map);
  3091     }
  3092 
  3093     template <typename Map>
  3094     UEdgeMapReader& readEdgeMap(std::string label, const Map& map) {
  3095       return _readDirMap<
  3096 	typename Traits::template Reader<typename Map::Value>, Map,
  3097 	typename _reader_bits::Arg<Map>::Type>(label, map);
  3098     }
  3099 
  3100     /// \brief Add a new directed edge map reader command for the reader.
  3101     ///
  3102     /// Add a new directed edge map reader command for the reader.
  3103     template <typename ItemReader, typename Map>
  3104     UEdgeMapReader& readEdgeMap(std::string label, Map& map, 
  3105 				    const ItemReader& ir = ItemReader()) {
  3106       return _readDirMap<ItemReader, Map, 
  3107         typename _reader_bits::Arg<Map>::Type>(label, map, ir);
  3108     }
  3109 
  3110     template <typename ItemReader, typename Map>
  3111     UEdgeMapReader& readEdgeMap(std::string label, const Map& map, 
  3112 				    const ItemReader& ir = ItemReader()) {
  3113       return _readDirMap<ItemReader, Map, 
  3114         typename _reader_bits::Arg<Map>::Type>(label, map, ir);
  3115     }
  3116 
  3117   private:
  3118 
  3119     template <typename ItemReader, typename Map, typename MapParameter>
  3120     UEdgeMapReader& _readDirMap(std::string label, MapParameter map,
  3121 				    const ItemReader& ir = ItemReader()) { 
  3122       checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
  3123       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
  3124       readUEdgeMap("+" + label, 
  3125                    _reader_bits::forwardComposeMap(graph, map), ir);
  3126       readUEdgeMap("-" + label, 
  3127                    _reader_bits::backwardComposeMap(graph, map), ir);
  3128       return *this;      
  3129     }
  3130 
  3131   public:
  3132 
  3133     /// \brief Add a new directed edge map skipper command for the reader.
  3134     ///
  3135     /// Add a new directed edge map skipper command for the reader.
  3136     template <typename ItemReader>
  3137     UEdgeMapReader& skipEdgeMap(std::string label, 
  3138                                 const ItemReader& ir = ItemReader()) {
  3139       skipUEdgeMap("+" + label, ir);
  3140       skipUEdgeMap("-" + label, ir);
  3141       return *this;
  3142     }
  3143 
  3144   protected:
  3145 
  3146     /// \brief Gives back true when the SectionReader can process 
  3147     /// the section with the given header line.
  3148     ///
  3149     /// It gives back true when the header line starts with \c \@mapset,
  3150     /// and the header line's name and the mapset's name are the same.
  3151     virtual bool header(const std::string& line) {
  3152       std::istringstream ls(line);
  3153       std::string command;
  3154       std::string id;
  3155       ls >> command >> id;
  3156       return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
  3157     }
  3158 
  3159     /// \brief Reader function of the section.
  3160     ///
  3161     /// It reads the content of the section.
  3162     virtual void read(std::istream& is) {
  3163       std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
  3164       std::string line;
  3165 
  3166       {
  3167         getline(is, line);
  3168         std::istringstream ls(line);
  3169         std::string id;
  3170         while (ls >> id) {
  3171           typename MapReaders::iterator it = readers.find(id);
  3172           if (it != readers.end()) {
  3173             it->second->touch();
  3174             index.push_back(it->second);
  3175           } else {
  3176             index.push_back(&skipper);
  3177           }
  3178         }
  3179       }
  3180       for (typename MapReaders::iterator it = readers.begin();
  3181 	   it != readers.end(); ++it) {
  3182 	if (!it->second->touched()) {
  3183 	  ErrorMessage msg;
  3184 	  msg << "Map not found in file: " << it->first;
  3185 	  throw IoParameterError(msg.message());
  3186 	}
  3187       }
  3188       while (getline(is, line)) {	
  3189 	std::istringstream ls(line);
  3190 	UEdge uedge = labelReader->read(ls);
  3191 	for (int i = 0; i < int(index.size()); ++i) {
  3192 	  index[i]->read(ls, uedge);
  3193 	}
  3194       }
  3195     }
  3196 
  3197     virtual void missing() {
  3198       if (readers.empty()) return;
  3199       ErrorMessage msg;
  3200       msg << "UEdgeMap section not found in file: @uedgemaps " << name;
  3201       throw IoParameterError(msg.message());
  3202     }
  3203 
  3204   private:
  3205 
  3206     const Graph& graph;   
  3207     std::string name;
  3208 
  3209     typedef std::map<std::string, 
  3210 		     _reader_bits::MapReaderBase<UEdge>*> MapReaders;
  3211    
  3212     MapReaders readers;
  3213     _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
  3214 
  3215     std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > labelReader;
  3216 
  3217   };
  3218 
  3219   /// \ingroup section_io
  3220   /// \brief SectionReader for retrieve what is in the file.
  3221   ///
  3222   /// SectionReader for retrieve what is in the file. If you want
  3223   /// to know which sections, maps and items are in the file
  3224   /// use the next code:
  3225   ///\code
  3226   /// LemonReader reader("input.lgf");
  3227   /// ContentReader content(reader);
  3228   /// reader.run();
  3229   ///\endcode
  3230   class ContentReader : public LemonReader::SectionReader {
  3231     typedef LemonReader::SectionReader Parent;
  3232   public:
  3233     /// \brief Constructor.
  3234     ///
  3235     /// Constructor for
  3236     ContentReader(LemonReader& _reader) : Parent(_reader) {}
  3237 
  3238     /// \brief Desctructor.
  3239     ///
  3240     /// Desctructor.
  3241     virtual ~ContentReader() {}
  3242 
  3243     /// \brief Gives back how many nodesets are in the file.
  3244     ///
  3245     /// Gives back how many nodesets are in the file.
  3246     int nodeSetNum() const {
  3247       return nodesets.size();
  3248     }
  3249 
  3250     /// \brief Gives back the name of nodeset on the indiced position.
  3251     ///
  3252     /// Gives back the name of nodeset on the indiced position.
  3253     std::string nodeSetName(int index) const {
  3254       return nodesets[index].name;
  3255     }
  3256 
  3257     /// \brief Gives back the map names of nodeset on the indiced position.
  3258     ///
  3259     /// Gives back the map names of nodeset on the indiced position.
  3260     const std::vector<std::string>& nodeSetMaps(int index) const {
  3261       return nodesets[index].items;
  3262     }
  3263 
  3264     /// \brief Gives back how many edgesets are in the file.
  3265     ///
  3266     /// Gives back how many edgesets are in the file.
  3267     int edgeSetNum() const {
  3268       return edgesets.size();
  3269     }
  3270 
  3271     /// \brief Gives back the name of edgeset on the indiced position.
  3272     ///
  3273     /// Gives back the name of edgeset on the indiced position.
  3274     std::string edgeSetName(int index) const {
  3275       return edgesets[index].name;
  3276     }
  3277 
  3278     /// \brief Gives back the map names of edgeset on the indiced position.
  3279     ///
  3280     /// Gives back the map names of edgeset on the indiced position.
  3281     const std::vector<std::string>& edgeSetMaps(int index) const {
  3282       return edgesets[index].items;
  3283     }
  3284 
  3285     /// \brief Gives back how many undirected edgesets are in the file.
  3286     ///
  3287     /// Gives back how many undirected edgesets are in the file.
  3288     int uEdgeSetNum() const {
  3289       return uedgesets.size();
  3290     }
  3291 
  3292     /// \brief Gives back the name of undirected edgeset on the indiced 
  3293     /// position.
  3294     ///
  3295     /// Gives back the name of undirected edgeset on the indiced position.
  3296     std::string uEdgeSetName(int index) const {
  3297       return uedgesets[index].name;
  3298     }
  3299 
  3300     /// \brief Gives back the map names of undirected edgeset on the indiced 
  3301     /// position.
  3302     ///
  3303     /// Gives back the map names of undirected edgeset on the indiced position.
  3304     const std::vector<std::string>& uEdgeSetMaps(int index) const {
  3305       return uedgesets[index].items;
  3306     }
  3307 
  3308     /// \brief Gives back how many labeled nodes section are in the file.
  3309     ///
  3310     /// Gives back how many labeled nodes section are in the file.
  3311     int nodesNum() const {
  3312       return nodes.size();
  3313     }
  3314 
  3315     /// \brief Gives back the name of labeled nodes section on the indiced 
  3316     /// position.
  3317     ///
  3318     /// Gives back the name of labeled nodes section on the indiced position.
  3319     std::string nodesName(int index) const {
  3320       return nodes[index].name;
  3321     }
  3322 
  3323     /// \brief Gives back the names of the labeled nodes in the indiced 
  3324     /// section.
  3325     ///
  3326     /// Gives back the names of the labeled nodes in the indiced section.
  3327     const std::vector<std::string>& nodesItems(int index) const {
  3328       return nodes[index].items;
  3329     }
  3330 
  3331     /// \brief Gives back how many labeled edges section are in the file.
  3332     ///
  3333     /// Gives back how many labeled edges section are in the file.
  3334     int edgesNum() const {
  3335       return edges.size();
  3336     }
  3337 
  3338     /// \brief Gives back the name of labeled edges section on the indiced 
  3339     /// position.
  3340     ///
  3341     /// Gives back the name of labeled edges section on the indiced position.
  3342     std::string edgesName(int index) const {
  3343       return edges[index].name;
  3344     }
  3345 
  3346     /// \brief Gives back the names of the labeled edges in the indiced 
  3347     /// section.
  3348     ///
  3349     /// Gives back the names of the labeled edges in the indiced section.
  3350     const std::vector<std::string>& edgesItems(int index) const {
  3351       return edges[index].items;
  3352     }
  3353  
  3354     /// \brief Gives back how many labeled undirected edges section are 
  3355     /// in the file.
  3356     ///
  3357     /// Gives back how many labeled undirected edges section are in the file.
  3358     int uEdgesNum() const {
  3359       return uedges.size();
  3360     }
  3361 
  3362     /// \brief Gives back the name of labeled undirected edges section 
  3363     /// on the indiced position.
  3364     ///
  3365     /// Gives back the name of labeled undirected edges section on the 
  3366     /// indiced position.
  3367     std::string uEdgesName(int index) const {
  3368       return uedges[index].name;
  3369     }
  3370 
  3371     /// \brief Gives back the names of the labeled undirected edges in 
  3372     /// the indiced section.
  3373     ///
  3374     /// Gives back the names of the labeled undirected edges in the 
  3375     /// indiced section.
  3376     const std::vector<std::string>& uEdgesItems(int index) const {
  3377       return uedges[index].items;
  3378     }
  3379 
  3380  
  3381     /// \brief Gives back how many attributes section are in the file.
  3382     ///
  3383     /// Gives back how many attributes section are in the file.
  3384     int attributesNum() const {
  3385       return attributes.size();
  3386     }
  3387 
  3388     /// \brief Gives back the name of attributes section on the indiced 
  3389     /// position.
  3390     ///
  3391     /// Gives back the name of attributes section on the indiced position.
  3392     std::string attributesName(int index) const {
  3393       return attributes[index].name;
  3394     }
  3395 
  3396     /// \brief Gives back the names of the attributes in the indiced section.
  3397     ///
  3398     /// Gives back the names of the attributes in the indiced section.
  3399     const std::vector<std::string>& attributesItems(int index) const {
  3400       return attributes[index].items;
  3401     }
  3402 
  3403     const std::vector<std::string>& otherSections() const {
  3404       return sections;
  3405     }
  3406 
  3407   protected:
  3408     
  3409     /// \brief Gives back true when the SectionReader can process 
  3410     /// the section with the given header line.
  3411     ///
  3412     /// It gives back true when the section is common section.
  3413     bool header(const std::string& line) {
  3414       std::istringstream ls(line);
  3415       std::string command, name;
  3416       ls >> command >> name;
  3417       if (command == "@nodeset") {
  3418 	current = command;
  3419 	nodesets.push_back(SectionInfo(name));
  3420       } else if (command == "@edgeset") {
  3421 	current = command;
  3422 	edgesets.push_back(SectionInfo(name));
  3423       } else if (command == "@uedgeset") {
  3424 	current = command;
  3425 	uedgesets.push_back(SectionInfo(name));
  3426       } else if (command == "@nodes") {
  3427 	current = command;
  3428 	nodes.push_back(SectionInfo(name));
  3429       } else if (command == "@edges") {
  3430 	current = command;
  3431 	edges.push_back(SectionInfo(name));
  3432       } else if (command == "@uedges") {
  3433 	current = command;
  3434 	uedges.push_back(SectionInfo(name));
  3435       } else if (command == "@attributes") {
  3436 	current = command;
  3437 	attributes.push_back(SectionInfo(name));
  3438       } else {
  3439 	sections.push_back(line);
  3440 	return false;
  3441       }
  3442       return true;
  3443     }
  3444 
  3445     /// \brief Retrieve the items from various sections.
  3446     ///
  3447     /// Retrieve the items from various sections.
  3448     void read(std::istream& is) {
  3449       if (current == "@nodeset") {
  3450 	readMapNames(is, nodesets.back().items);
  3451       } else if (current == "@edgeset") {
  3452 	readMapNames(is, edgesets.back().items);
  3453       } else if (current == "@uedgeset") {
  3454 	readMapNames(is, uedgesets.back().items);
  3455       } else if (current == "@nodes") {
  3456 	readItemNames(is, nodes.back().items);
  3457       } else if (current == "@edges") {
  3458 	readItemNames(is, edges.back().items);
  3459       } else if (current == "@uedges") {
  3460 	readItemNames(is, uedges.back().items);
  3461       } else if (current == "@attributes") {
  3462 	readItemNames(is, attributes.back().items);
  3463       }
  3464     }    
  3465 
  3466   private:
  3467 
  3468     void readMapNames(std::istream& is, std::vector<std::string>& maps) {
  3469       std::string line, name;
  3470       std::getline(is, line);
  3471       std::istringstream ls(line);
  3472       while (ls >> name) {
  3473 	maps.push_back(name);
  3474       }
  3475       while (getline(is, line));
  3476     }
  3477 
  3478     void readItemNames(std::istream& is, std::vector<std::string>& maps) {
  3479       std::string line, name;
  3480       while (std::getline(is, line)) {
  3481 	std::istringstream ls(line);
  3482 	ls >> name;
  3483 	maps.push_back(name);
  3484       }
  3485     }
  3486 
  3487     struct SectionInfo {
  3488       std::string name;
  3489       std::vector<std::string> items;
  3490 
  3491       SectionInfo(const std::string& _name) : name(_name) {}
  3492     };
  3493 
  3494     std::vector<SectionInfo> nodesets;
  3495     std::vector<SectionInfo> edgesets;
  3496     std::vector<SectionInfo> uedgesets;
  3497 
  3498     std::vector<SectionInfo> nodes;
  3499     std::vector<SectionInfo> edges;
  3500     std::vector<SectionInfo> uedges;
  3501 
  3502     std::vector<SectionInfo> attributes;
  3503 
  3504     std::vector<std::string> sections;
  3505 
  3506     std::string current;
  3507 
  3508   };
  3509 
  3510 }
  3511 #endif