lemon/lemon_reader.h
author deba
Mon, 27 Feb 2006 10:17:33 +0000
changeset 1985 8782ff6fd98a
parent 1946 17eb3eaad9f8
child 1993 2115143eceea
permissions -rw-r--r--
Bug fix
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2006
     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 io_group
    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/utility.h>
    39 #include <lemon/bits/item_reader.h>
    40 
    41 #include <lemon/xy.h>
    42 
    43 #include <lemon/concept_check.h>
    44 #include <lemon/concept/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       typename Ref<Map>::Type map;
   121       const Graph& graph;
   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       typename Ref<Map>::Type map;
   151       const Graph& graph;
   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<XMap<Map> > { 
   187       typedef XMap<Map> Type;
   188     };
   189     template <typename Map>
   190     struct Arg<XMap<Map> > { 
   191       typedef const XMap<Map>& Type;
   192     };
   193 
   194     template <typename Map>
   195     struct Ref<YMap<Map> > { 
   196       typedef YMap<Map> Type;
   197     };
   198     template <typename Map>
   199     struct Arg<YMap<Map> > { 
   200       typedef const 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 	  throw DataFormatError("Invalid label error");
   258 	}
   259       }      
   260     };
   261 
   262     template <typename _Item, typename _Reader>
   263     class SkipReaderInverter : public MapInverterBase<_Item> {
   264     public:
   265       typedef _Item Item;
   266       typedef _Reader Reader;
   267       typedef typename Reader::Value Value;
   268       typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
   269 
   270       Reader reader;
   271 
   272       SkipReaderInverter(const Reader& _reader) 
   273 	: reader(_reader) {}
   274 
   275       virtual ~SkipReaderInverter() {}
   276 
   277       virtual void read(std::istream& is, const Item& item) {
   278 	Value value;
   279 	reader.read(is, value);
   280 	typename Inverse::iterator it = inverse.find(value);
   281 	if (it == inverse.end()) {
   282 	  inverse.insert(std::make_pair(value, item));
   283 	} else {
   284 	  throw DataFormatError("Multiple label occurence error");
   285 	}
   286       }
   287 
   288       virtual Item read(std::istream& is) const {
   289 	Value value;
   290 	reader.read(is, value);	
   291 	typename Inverse::const_iterator it = inverse.find(value);
   292 	if (it != inverse.end()) {
   293 	  return it->second;
   294 	} else {
   295 	  throw DataFormatError("Invalid label error");
   296 	}
   297       }
   298 
   299     private:
   300       Inverse inverse;
   301     };
   302 
   303     template <typename _Item>    
   304     class MapReaderBase {
   305     public:
   306       typedef _Item Item;
   307 
   308       MapReaderBase() { _touched = false; }
   309       
   310       void touch() { _touched = true; }
   311       bool touched() const { return _touched; }
   312 
   313       virtual ~MapReaderBase() {}
   314 
   315       virtual void read(std::istream& is, const Item& item) = 0;
   316       virtual MapInverterBase<_Item>* getInverter() = 0;
   317 
   318     private:      
   319       bool _touched;
   320 
   321     };
   322 
   323     template <typename _Item, typename _Map, typename _Reader>
   324     class MapReader : public MapReaderBase<_Item> {
   325     public:
   326       typedef _Map Map;
   327       typedef _Reader Reader;
   328       typedef typename Reader::Value Value;
   329       typedef _Item Item;
   330       
   331       typename _reader_bits::Ref<Map>::Type map;
   332       Reader reader;
   333 
   334       MapReader(typename _reader_bits::Arg<Map>::Type _map, 
   335 		const Reader& _reader) 
   336 	: map(_map), reader(_reader) {}
   337 
   338       virtual ~MapReader() {}
   339 
   340       virtual void read(std::istream& is, const Item& item) {
   341 	Value value;
   342 	reader.read(is, value);
   343 	map.set(item, value);
   344       }
   345 
   346       virtual MapInverterBase<_Item>* getInverter() {
   347 	return new MapReaderInverter<Item, Map, Reader>(map, reader);
   348       }
   349     };
   350 
   351 
   352     template <typename _Item, typename _Reader>
   353     class SkipReader : public MapReaderBase<_Item> {
   354     public:
   355       typedef _Reader Reader;
   356       typedef typename Reader::Value Value;
   357       typedef _Item Item;
   358 
   359       Reader reader;
   360       SkipReader(const Reader& _reader) : reader(_reader) {}
   361 
   362       virtual ~SkipReader() {}
   363 
   364       virtual void read(std::istream& is, const Item&) {
   365 	Value value;
   366 	reader.read(is, value);
   367       }      
   368 
   369       virtual MapInverterBase<Item>* getInverter() {
   370 	return new SkipReaderInverter<Item, Reader>(reader);
   371       }
   372     };
   373 
   374     template <typename _Item>
   375     class LabelReaderBase {
   376     public:
   377       typedef _Item Item;
   378       virtual ~LabelReaderBase() {}
   379       virtual Item read(std::istream& is) const = 0;
   380       virtual bool isLabelReader() const = 0;
   381     };
   382 
   383     template <typename _Item, typename _BoxedLabelReader>
   384     class LabelReader : public LabelReaderBase<_Item> {
   385     public:
   386       typedef _Item Item;
   387       typedef _BoxedLabelReader BoxedLabelReader;
   388       
   389       const BoxedLabelReader& boxedLabelReader;
   390 
   391       LabelReader(const BoxedLabelReader& _boxedLabelReader) 
   392 	: boxedLabelReader(_boxedLabelReader) {}
   393 
   394       virtual Item read(std::istream& is) const {
   395 	Item item;
   396 	boxedLabelReader.readLabel(is, item);
   397 	return item;
   398       }
   399 
   400       virtual bool isLabelReader() const {
   401 	return boxedLabelReader.isLabelReader();
   402       }
   403     };
   404 
   405     template <typename _Item>
   406     class ItemStore {
   407     public:
   408 
   409       typedef _Item Item;
   410 
   411       ItemStore(Item& _item) : item(&_item) { 
   412 	_touched = false; 
   413       }
   414       
   415       void touch() { _touched = true; }
   416       bool touched() const { return _touched; }
   417 
   418       void read(const Item& _item) {
   419 	*item = _item;
   420       }
   421       
   422     private:
   423       Item* item;
   424       bool _touched;
   425     };
   426 
   427     class ValueReaderBase {
   428     public:
   429       virtual void read(std::istream&) {};
   430       ValueReaderBase() { _touched = false; }
   431 
   432       void touch() { _touched = true; }
   433       bool touched() const { return _touched; }
   434 
   435       virtual ~ValueReaderBase() {}
   436     private:
   437       bool _touched;
   438     };
   439 
   440     template <typename _Value, typename _Reader>
   441     class ValueReader : public ValueReaderBase {
   442     public:
   443       typedef _Value Value;
   444       typedef _Reader Reader;
   445 
   446       ValueReader(Value& _value, const Reader& _reader)
   447  	: value(_value), reader(_reader) {}
   448 
   449       virtual void read(std::istream& is) {
   450 	reader.read(is, value);
   451       }
   452     private:
   453       Value& value;
   454       Reader reader;
   455     };
   456 
   457   }
   458 
   459   /// \ingroup io_group
   460   /// \brief Lemon Format reader class.
   461   /// 
   462   /// The Lemon Format contains several sections. We do not want to
   463   /// determine what sections are in a lemon file we give only a framework
   464   /// to read a section oriented format.
   465   ///
   466   /// In the Lemon Format each section starts with a line contains a \c \@
   467   /// character on the first not white space position. This line is the
   468   /// header line of the section. Each next lines belong to this section
   469   /// while it does not starts with \c \@ character. This line can start a 
   470   /// new section or if it can close the file with the \c \@end line.
   471   /// The file format ignore the empty and comment lines. The line is
   472   /// comment line if it starts with a \c # character. 
   473   ///
   474   /// The framework provides an abstract LemonReader::SectionReader class
   475   /// what defines the interface of a SectionReader. The SectionReader
   476   /// has the \c header() member function what get a header line string and
   477   /// decides if it want to process the next section. Several SectionReaders
   478   /// can be attached to an LemonReader and the first attached what can
   479   /// process the section will be used. Its \c read() member will called
   480   /// with a stream contains the section. From this stream the empty and
   481   /// comment lines are filtered out.
   482   ///
   483   /// \relates GraphReader
   484   /// \relates NodeSetReader
   485   /// \relates EdgeSetReader
   486   /// \relates NodesReader
   487   /// \relates EdgesReader
   488   /// \relates AttributeReader
   489   class LemonReader {
   490   private:
   491     
   492     class FilterStreamBuf : public std::streambuf {
   493     public:
   494 
   495       typedef std::streambuf Parent;
   496       typedef Parent::char_type char_type;
   497       FilterStreamBuf(std::istream& is, int& num) 
   498 	: _is(is), _base(0), _eptr(0), 
   499 	  _num(num), skip_state(after_endl) {}
   500 
   501     protected:
   502 
   503       enum skip_state_type {
   504 	no_skip,
   505 	after_endl,
   506 	comment_line
   507       };
   508 
   509       char_type small_buf[1];
   510 
   511 
   512       std::istream& _is;
   513 
   514       char_type* _base;
   515       char_type* _eptr;
   516 
   517       int& _num;
   518 
   519       skip_state_type skip_state;
   520 
   521 
   522       char_type* base() { return _base; }
   523 
   524       char_type* eptr() { return _eptr; }
   525 
   526       int blen() { return _eptr - _base; }
   527 
   528       void setb(char_type* buf, int len) {
   529 	_base = buf;
   530 	_eptr = buf + len;
   531       }
   532   
   533       virtual std::streambuf* setbuf(char *buf, std::streamsize len) {
   534 	if (base()) return 0;
   535 	if (buf != 0 && len >= (int)sizeof(small_buf)) {
   536 	  setb(buf, len);
   537 	} else {
   538 	  setb(small_buf, sizeof(small_buf));
   539 	}
   540 	setg(0, 0, 0);
   541 	return this;
   542       }
   543 
   544       bool put_char(char c) {
   545 	switch (skip_state) {
   546 	case no_skip:
   547 	  switch (c) {
   548 	  case '\n': 
   549 	    skip_state = after_endl;
   550 	    return true;
   551 	  default:
   552 	    return true;
   553 	  }
   554 	case after_endl:
   555 	  switch (c) {
   556 	  case '@':
   557 	    return false;
   558 	  case '\n': 
   559 	    return false;
   560 	  case '#':
   561 	    skip_state = comment_line;
   562 	    return false;
   563 	  default:
   564 	    if (!isspace(c)) {
   565 	      skip_state = no_skip;
   566 	      return true;
   567 	    } else {
   568 	      return false;
   569 	    }
   570 	  }
   571 	  break;
   572 	case comment_line:
   573 	  switch (c) {
   574 	  case '\n': 
   575 	    skip_state = after_endl;
   576 	    return false;
   577 	  default:
   578 	    return false;
   579 	  }
   580 	}
   581 	return false;
   582       }
   583 
   584       virtual int underflow() {
   585 	char c;
   586 	if (_is.read(&c, 1)) {
   587 	  _is.putback(c);
   588 	  if (c == '@') {
   589 	    return EOF;
   590 	  }
   591 	} else {
   592 	  return EOF;
   593 	}
   594 	char_type *ptr;
   595 	for (ptr = base(); ptr != eptr(); ++ptr) {
   596 	  if (_is.read(&c, 1)) {
   597 	    if (c == '\n') ++_num;
   598 	    if (put_char(c)) {
   599 	      *ptr = c;
   600 	    } else {
   601 	      if (skip_state == after_endl && c == '@') {
   602 		_is.putback('@');
   603 		break;
   604 	      }
   605 	      --ptr;
   606 	    }
   607 	  } else {
   608 	    break;
   609 	  }
   610 	}
   611 	setg(base(), base(), ptr);
   612 	return *base();
   613       }
   614 
   615       virtual int sync() {
   616 	return EOF;
   617       }
   618     };
   619 
   620   public:
   621 
   622     /// \brief Abstract base class for reading a section.
   623     ///
   624     /// This class has an \c header() member function what get a 
   625     /// header line string and decides if it want to process the next 
   626     /// section. Several SectionReaders can be attached to an LemonReader 
   627     /// and the first attached what can process the section will be used. 
   628     /// Its \c read() member will called with a stream contains the section. 
   629     /// From this stream the empty lines and comments are filtered out.
   630     class SectionReader {
   631       friend class LemonReader;
   632     protected:
   633       /// \brief Constructor for SectionReader.
   634       ///
   635       /// Constructor for SectionReader. It attach this reader to
   636       /// the given LemonReader.
   637       SectionReader(LemonReader& reader) {
   638 	reader.attach(*this);
   639       }
   640 
   641       virtual ~SectionReader() {}
   642 
   643       /// \brief Gives back true when the SectionReader can process 
   644       /// the section with the given header line.
   645       ///
   646       /// It gives back true when the SectionReader can process
   647       /// the section with the given header line.
   648       virtual bool header(const std::string& line) = 0;
   649 
   650       /// \brief Reader function of the section.
   651       ///
   652       /// It reads the content of the section.
   653       virtual void read(std::istream& is) = 0;
   654     };
   655 
   656     /// \brief Constructor for LemonReader.
   657     ///
   658     /// Constructor for LemonReader which reads from the given stream.
   659     LemonReader(std::istream& _is) 
   660       : is(&_is), own_is(false) {}
   661 
   662     /// \brief Constructor for LemonReader.
   663     ///
   664     /// Constructor for LemonReader which reads from the given file.
   665     LemonReader(const std::string& filename) 
   666       : is(0), own_is(true) {
   667       is = new std::ifstream(filename.c_str());
   668       if (is->fail()) {
   669 	throw FileOpenError(filename);
   670       }
   671     }
   672 
   673     /// \brief Desctructor for LemonReader.
   674     ///
   675     /// Desctructor for LemonReader.
   676     ~LemonReader() {
   677       if (own_is) {
   678 	delete is;
   679       }
   680     }
   681 
   682   private:
   683     LemonReader(const LemonReader&);
   684     void operator=(const LemonReader&);
   685 
   686     void attach(SectionReader& reader) {
   687       readers.push_back(&reader);
   688     }
   689 
   690   public:
   691     /// \brief Executes the LemonReader.
   692     /// 
   693     /// It executes the LemonReader.
   694     void run() {
   695       int line_num = 0;
   696       std::string line;
   697       try {
   698 	while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
   699 	  SectionReaders::iterator it;
   700 	  for (it = readers.begin(); it != readers.end(); ++it) {
   701 	    if ((*it)->header(line)) {
   702 	      char buf[2048];
   703 	      FilterStreamBuf buffer(*is, line_num);
   704 	      buffer.pubsetbuf(buf, sizeof(buf));
   705 	      std::istream is(&buffer);
   706 	      (*it)->read(is);
   707 	      break;
   708 	    }
   709 	  }
   710 	}
   711       } catch (DataFormatError& error) {
   712 	error.line(line_num);
   713 	throw error;
   714       }	
   715     }
   716 
   717 
   718   private:
   719 
   720     std::istream* is;
   721     bool own_is;
   722 
   723     typedef std::vector<SectionReader*> SectionReaders;
   724     SectionReaders readers;
   725 
   726   };
   727 
   728   /// \ingroup io_group
   729   /// \brief SectionReader for reading a graph's nodeset.
   730   ///
   731   /// The lemon format can store multiple graph nodesets with several maps.
   732   /// The nodeset section's header line is \c \@nodeset \c nodeset_name, but the
   733   /// \c nodeset_name may be empty.
   734   ///
   735   /// The first line of the section contains the names of the maps separated
   736   /// with white spaces. Each next lines describes a node in the nodeset, and
   737   /// contains the mapped values for each map.
   738   ///
   739   /// If the nodeset contains an \c "label" named map then it will be regarded
   740   /// as id map. This map should contain only unique values and when the 
   741   /// \c readLabel() member will read a value from the given stream it will
   742   /// give back that node which is mapped to this value.
   743   ///
   744   /// \relates LemonReader
   745   template <typename _Graph, typename _Traits = DefaultReaderTraits>
   746   class NodeSetReader : public LemonReader::SectionReader {
   747     typedef LemonReader::SectionReader Parent;
   748   public:
   749 
   750     typedef _Graph Graph;
   751     typedef _Traits Traits;
   752     typedef typename Graph::Node Node;
   753     typedef typename Traits::Skipper DefaultSkipper;
   754 
   755     /// \brief Constructor.
   756     ///
   757     /// Constructor for NodeSetReader. It creates the NodeSetReader and
   758     /// attach it into the given LemonReader. The nodeset reader will
   759     /// add the readed nodes to the given Graph. The reader will read
   760     /// the section when the \c section_name and the \c _name are the same. 
   761     NodeSetReader(LemonReader& _reader, 
   762 		  Graph& _graph, 
   763 		  const std::string& _name = std::string(),
   764 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   765       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {} 
   766 
   767 
   768     /// \brief Destructor.
   769     ///
   770     /// Destructor for NodeSetReader.
   771     virtual ~NodeSetReader() {
   772       for (typename MapReaders::iterator it = readers.begin(); 
   773 	   it != readers.end(); ++it) {
   774 	delete it->second;
   775       }
   776     }
   777 
   778   private:
   779     NodeSetReader(const NodeSetReader&);
   780     void operator=(const NodeSetReader&);
   781   
   782   public:
   783 
   784     /// \brief Add a new node map reader command for the reader.
   785     ///
   786     /// Add a new node map reader command for the reader.
   787     template <typename Map>
   788     NodeSetReader& readNodeMap(std::string name, Map& map) {
   789       return _readMap<
   790 	typename Traits::template Reader<typename Map::Value>, Map,
   791 	typename _reader_bits::Arg<Map>::Type>(name, map);
   792     }
   793 
   794     template <typename Map>
   795     NodeSetReader& readNodeMap(std::string name, const Map& map) {
   796       return _readMap<
   797 	typename Traits::template Reader<typename Map::Value>, Map,
   798 	typename _reader_bits::Arg<Map>::Type>(name, map);
   799     }
   800 
   801     /// \brief Add a new node map reader command for the reader.
   802     ///
   803     /// Add a new node map reader command for the reader.
   804     template <typename Reader, typename Map>
   805     NodeSetReader& readNodeMap(std::string name, Map& map, 
   806 			       const Reader& reader = Reader()) {
   807       return _readMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
   808 	(name, map, reader);
   809     }
   810 
   811     template <typename Reader, typename Map>
   812     NodeSetReader& readNodeMap(std::string name, const Map& map, 
   813 			       const Reader& reader = Reader()) {
   814       return _readMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
   815 	(name, map, reader);
   816     }
   817 
   818   private:
   819 
   820     template <typename Reader, typename Map, typename MapParameter>
   821     NodeSetReader& _readMap(std::string name, MapParameter map, 
   822 			    const Reader& reader = Reader()) {
   823       checkConcept<concept::WriteMap<Node, typename Map::Value>, Map>();
   824       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
   825       if (readers.find(name) != readers.end()) {
   826 	ErrorMessage msg;
   827 	msg << "Multiple read rule for node map: " << name;
   828 	throw IOParameterError(msg.message());
   829       }      
   830       readers.insert(
   831         make_pair(name, new _reader_bits::
   832 		  MapReader<Node, Map, Reader>(map, reader)));
   833       return *this;
   834     }
   835 
   836   public:
   837 
   838     /// \brief Add a new node map skipper command for the reader.
   839     ///
   840     /// Add a new node map skipper command for the reader.
   841     template <typename Reader>
   842     NodeSetReader& skipNodeMap(std::string name, 
   843 			   const Reader& reader = Reader()) {
   844       if (readers.find(name) != readers.end()) {
   845 	ErrorMessage msg;
   846 	msg << "Multiple read rule for node map: " << name;
   847 	throw IOParameterError(msg.message());
   848       }
   849       readers.insert(make_pair(name, new _reader_bits::
   850 			       SkipReader<Node, Reader>(reader)));
   851       return *this;
   852     }
   853 
   854   protected:
   855 
   856     /// \brief Gives back true when the SectionReader can process 
   857     /// the section with the given header line.
   858     ///
   859     /// It gives back true when the header line starts with \c \@nodeset,
   860     /// and the header line's name and the nodeset's name are the same.
   861     virtual bool header(const std::string& line) {
   862       std::istringstream ls(line);
   863       std::string command;
   864       std::string id;
   865       ls >> command >> name;
   866       return command == "@nodeset" && name == id;
   867     }
   868 
   869     /// \brief Reader function of the section.
   870     ///
   871     /// It reads the content of the section.
   872     virtual void read(std::istream& is) {
   873       std::vector<_reader_bits::MapReaderBase<Node>* > index;
   874       std::string line;
   875 
   876       getline(is, line);
   877       std::istringstream ls(line);
   878       std::string id;
   879       while (ls >> id) {
   880 	typename MapReaders::iterator it = readers.find(id);
   881 	if (it != readers.end()) {
   882 	  it->second->touch();
   883 	  index.push_back(it->second);
   884 	} else {
   885 	  index.push_back(&skipper);
   886 	}
   887 	if (id == "label" || (id =="id" && inverter.get() == 0)) {
   888 	  inverter.reset(index.back()->getInverter());
   889 	  index.back() = inverter.get();
   890 	}
   891       }
   892       for (typename MapReaders::iterator it = readers.begin();
   893 	   it != readers.end(); ++it) {
   894 	if (!it->second->touched()) {
   895 	  ErrorMessage msg;
   896 	  msg << "Map not found in file: " << it->first;
   897 	  throw IOParameterError(msg.message());
   898 	}
   899       }
   900       while (getline(is, line)) {	
   901 	Node node = graph.addNode();
   902 	std::istringstream ls(line);
   903 	for (int i = 0; i < (int)index.size(); ++i) {
   904 	  index[i]->read(ls, node);
   905 	}
   906       }
   907     }
   908 
   909   public:
   910 
   911     /// \brief Returns true if the nodeset can give back the node by its label.
   912     ///
   913     /// Returns true if the nodeset can give back the node by its label.
   914     /// It is possible only if an "label" named map was read.
   915     bool isLabelReader() const {
   916       return inverter.get() != 0;
   917     }
   918 
   919     /// \brief Gives back the node by its label.
   920     ///
   921     /// It reads an id from the stream and gives back which node belongs to
   922     /// it. It is possible only if there was read an "label" named map.
   923     void readLabel(std::istream& is, Node& node) const {
   924       node = inverter->read(is);
   925     } 
   926 
   927   private:
   928 
   929     typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
   930     MapReaders readers;
   931    
   932     Graph& graph;   
   933     std::string name;
   934     _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
   935 
   936     std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
   937   };
   938 
   939   /// \ingroup io_group
   940   /// \brief SectionReader for reading a graph's edgeset.
   941   ///
   942   /// The lemon format can store multiple graph edgesets with several maps.
   943   /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but the
   944   /// \c edgeset_name may be empty.
   945   ///
   946   /// The first line of the section contains the names of the maps separated
   947   /// with white spaces. Each next lines describes an edge in the edgeset. The
   948   /// line contains the source and the target nodes' id and the mapped 
   949   /// values for each map.
   950   ///
   951   /// If the edgeset contains an \c "label" named map then it will be regarded
   952   /// as id map. This map should contain only unique values and when the 
   953   /// \c readLabel() member will read a value from the given stream it will
   954   /// give back that edge which is mapped to this value.
   955   ///
   956   /// The edgeset reader needs a node id reader to identify which nodes
   957   /// have to be connected. If a NodeSetReader reads an "label" named map,
   958   /// it will be able to resolve the nodes by ids.
   959   ///
   960   /// \relates LemonReader
   961   template <typename _Graph, typename _Traits = DefaultReaderTraits>
   962   class EdgeSetReader : public LemonReader::SectionReader {
   963     typedef LemonReader::SectionReader Parent;
   964   public:
   965 
   966     typedef _Graph Graph;
   967     typedef _Traits Traits;
   968     typedef typename Graph::Node Node;
   969     typedef typename Graph::Edge Edge;
   970     typedef typename Traits::Skipper DefaultSkipper;
   971 
   972     /// \brief Constructor.
   973     ///
   974     /// Constructor for EdgeSetReader. It creates the EdgeSetReader and
   975     /// attach it into the given LemonReader. The edgeset reader will
   976     /// add the readed edges to the given Graph. It will use the given
   977     /// node id reader to read the source and target nodes of the edges.
   978     /// The reader will read the section only if the \c _name and the 
   979     /// \c edgset_name are the same. 
   980     template <typename NodeLabelReader>
   981     EdgeSetReader(LemonReader& _reader, 
   982 		  Graph& _graph, 
   983 		  const NodeLabelReader& _nodeLabelReader, 
   984 		  const std::string& _name = std::string(),
   985 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   986       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
   987       checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
   988       nodeLabelReader.reset(new _reader_bits::
   989 			 LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
   990     }
   991     /// \brief Destructor.
   992     ///
   993     /// Destructor for EdgeSetReader.
   994     virtual ~EdgeSetReader() {
   995       for (typename MapReaders::iterator it = readers.begin(); 
   996 	   it != readers.end(); ++it) {
   997 	delete it->second;
   998       }
   999     }
  1000 
  1001   private:
  1002     EdgeSetReader(const EdgeSetReader&);
  1003     void operator=(const EdgeSetReader&);
  1004 
  1005   public:
  1006 
  1007     /// \brief Add a new edge map reader command for the reader.
  1008     ///
  1009     /// Add a new edge map reader command for the reader.
  1010     template <typename Map>
  1011     EdgeSetReader& readEdgeMap(std::string name, Map& map) {
  1012       return _readMap<
  1013 	typename Traits::template Reader<typename Map::Value>, Map,
  1014 	typename _reader_bits::Arg<Map>::Type>(name, map);
  1015     }
  1016 
  1017     template <typename Map>
  1018     EdgeSetReader& readEdgeMap(std::string name, const Map& map) {
  1019       return _readMap<
  1020 	typename Traits::template Reader<typename Map::Value>, Map,
  1021 	typename _reader_bits::Arg<Map>::Type>(name, map);
  1022     }
  1023 
  1024     /// \brief Add a new edge map reader command for the reader.
  1025     ///
  1026     /// Add a new edge map reader command for the reader.
  1027     template <typename Reader, typename Map>
  1028     EdgeSetReader& readEdgeMap(std::string name, Map& map, 
  1029 			   const Reader& reader = Reader()) {
  1030       return _readMap<Reader, Map,
  1031 	typename _reader_bits::Arg<Map>::Type>(name, map, reader);
  1032     }
  1033 
  1034     template <typename Reader, typename Map>
  1035     EdgeSetReader& readEdgeMap(std::string name, const Map& map, 
  1036 			       const Reader& reader = Reader()) {
  1037       return _readMap<Reader, Map,
  1038 	typename _reader_bits::Arg<Map>::Type>(name, map, reader);
  1039     }
  1040 
  1041   private:
  1042 
  1043     template <typename Reader, typename Map, typename MapParameter>
  1044     EdgeSetReader& _readMap(std::string name, MapParameter map, 
  1045 			    const Reader& reader = Reader()) {
  1046       checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
  1047       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
  1048       if (readers.find(name) != readers.end()) {
  1049 	ErrorMessage msg;
  1050 	msg << "Multiple read rule for edge map: " << name;
  1051 	throw IOParameterError(msg.message());
  1052       }
  1053       readers.insert(
  1054 	make_pair(name, new _reader_bits::
  1055 		  MapReader<Edge, Map, Reader>(map, reader)));
  1056       return *this;
  1057     }
  1058 
  1059   public:
  1060 
  1061     /// \brief Add a new edge map skipper command for the reader.
  1062     ///
  1063     /// Add a new edge map skipper command for the reader.
  1064     template <typename Reader>
  1065     EdgeSetReader& skipEdgeMap(std::string name, 
  1066 			       const Reader& reader = Reader()) {
  1067       if (readers.find(name) != readers.end()) {
  1068 	ErrorMessage msg;
  1069 	msg << "Multiple read rule for edge map: " << name;
  1070 	throw IOParameterError(msg.message());
  1071       }
  1072       readers.insert(make_pair(name, new _reader_bits::
  1073 			       SkipReader<Edge, Reader>(reader)));
  1074       return *this;
  1075     }
  1076 
  1077   protected:
  1078 
  1079     /// \brief Gives back true when the SectionReader can process 
  1080     /// the section with the given header line.
  1081     ///
  1082     /// It gives back true when the header line starts with \c \@edgeset,
  1083     /// and the header line's name and the edgeset's name are the same.
  1084     virtual bool header(const std::string& line) {
  1085       std::istringstream ls(line);
  1086       std::string command;
  1087       std::string id;
  1088       ls >> command >> name;
  1089       return command == "@edgeset" && name == id;
  1090     }
  1091 
  1092     /// \brief Reader function of the section.
  1093     ///
  1094     /// It reads the content of the section.
  1095     virtual void read(std::istream& is) {
  1096       if (!nodeLabelReader->isLabelReader()) {
  1097 	throw DataFormatError("Cannot find nodeset or label map");
  1098       }
  1099       std::vector<_reader_bits::MapReaderBase<Edge>* > index;
  1100       std::string line;
  1101 
  1102       getline(is, line);
  1103       std::istringstream ls(line);	
  1104       std::string id;
  1105       while (ls >> id) {
  1106 	typename MapReaders::iterator it = readers.find(id);
  1107 	if (it != readers.end()) {
  1108 	  index.push_back(it->second);
  1109 	  it->second->touch();
  1110 	} else {
  1111 	  index.push_back(&skipper);
  1112 	}
  1113 	if (id == "label" || (id =="id" && inverter.get() == 0)) {
  1114 	  inverter.reset(index.back()->getInverter());
  1115 	  index.back() = inverter.get();
  1116 	}
  1117       }
  1118       for (typename MapReaders::iterator it = readers.begin();
  1119 	   it != readers.end(); ++it) {
  1120 	if (!it->second->touched()) {
  1121 	  ErrorMessage msg;
  1122 	  msg << "Map not found in file: " << it->first;
  1123 	  throw IOParameterError(msg.message());
  1124 	}
  1125       }
  1126       while (getline(is, line)) {	
  1127 	std::istringstream ls(line);
  1128 	Node from = nodeLabelReader->read(ls);
  1129 	Node to = nodeLabelReader->read(ls);
  1130 	Edge edge = graph.addEdge(from, to);
  1131 	for (int i = 0; i < (int)index.size(); ++i) {
  1132 	  index[i]->read(ls, edge);
  1133 	}
  1134       }
  1135     }
  1136 
  1137   public:
  1138 
  1139     /// \brief Returns true if the edgeset can give back the edge by its label.
  1140     ///
  1141     /// Returns true if the edgeset can give back the edge by its label.
  1142     /// It is possible only if an "label" named map was read.
  1143     bool isLabelReader() const {
  1144       return inverter.get() != 0;
  1145     }
  1146 
  1147     /// \brief Gives back the edge by its label.
  1148     ///
  1149     /// It reads an id from the stream and gives back which edge belongs to
  1150     /// it. It is possible only if there was read an "label" named map.
  1151     void readLabel(std::istream& is, Edge& edge) const {
  1152       edge = inverter->read(is);
  1153     } 
  1154 
  1155   private:
  1156 
  1157     typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
  1158     MapReaders readers;
  1159    
  1160     Graph& graph;   
  1161     std::string name;
  1162     _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
  1163 
  1164     std::auto_ptr<_reader_bits::MapInverterBase<Edge> > inverter;
  1165     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
  1166   };
  1167 
  1168   /// \ingroup io_group
  1169   /// \brief SectionReader for reading a undirected graph's edgeset.
  1170   ///
  1171   /// The lemon format can store multiple undirected edgesets with several 
  1172   /// maps. The undirected edgeset section's header line is \c \@uedgeset 
  1173   /// \c uedgeset_name, but the \c uedgeset_name may be empty.
  1174   ///
  1175   /// The first line of the section contains the names of the maps separated
  1176   /// with white spaces. Each next lines describes an edge in the edgeset. The
  1177   /// line contains the connected nodes' id and the mapped values for each map.
  1178   ///
  1179   /// The section can handle the directed as a syntactical sugar. Two
  1180   /// undirected edge map describes one directed edge map. This two maps
  1181   /// are the forward map and the backward map and the names of this map
  1182   /// is near the same just with a prefix \c '+' or \c '-' character 
  1183   /// difference.
  1184   ///
  1185   /// If the edgeset contains an \c "label" named map then it will be regarded
  1186   /// as id map. This map should contain only unique values and when the 
  1187   /// \c readLabel() member will read a value from the given stream it will
  1188   /// give back that uicted edge which is mapped to this value.
  1189   ///
  1190   /// The undirected edgeset reader needs a node id reader to identify which 
  1191   /// nodes have to be connected. If a NodeSetReader reads an "label" named map,
  1192   /// it will be able to resolve the nodes by ids.
  1193   ///
  1194   /// \relates LemonReader
  1195   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  1196   class UEdgeSetReader : public LemonReader::SectionReader {
  1197     typedef LemonReader::SectionReader Parent;
  1198   public:
  1199 
  1200     typedef _Graph Graph;
  1201     typedef _Traits Traits;
  1202     typedef typename Graph::Node Node;
  1203     typedef typename Graph::Edge Edge;
  1204     typedef typename Graph::UEdge UEdge;
  1205     typedef typename Traits::Skipper DefaultSkipper;
  1206 
  1207     /// \brief Constructor.
  1208     ///
  1209     /// Constructor for UEdgeSetReader. It creates the UEdgeSetReader 
  1210     /// and attach it into the given LemonReader. The undirected edgeset 
  1211     /// reader will add the readed undirected edges to the given Graph. It 
  1212     /// will use the given node id reader to read the source and target 
  1213     /// nodes of the edges. The reader will read the section only if the 
  1214     /// \c _name and the \c uedgset_name are the same. 
  1215     template <typename NodeLabelReader>
  1216     UEdgeSetReader(LemonReader& _reader, 
  1217 		       Graph& _graph, 
  1218 		       const NodeLabelReader& _nodeLabelReader, 
  1219 		       const std::string& _name = std::string(),
  1220 		       const DefaultSkipper& _skipper = DefaultSkipper()) 
  1221       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
  1222       checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
  1223       nodeLabelReader.reset(new _reader_bits::
  1224 			 LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
  1225     }
  1226     /// \brief Destructor.
  1227     ///
  1228     /// Destructor for UEdgeSetReader.
  1229     virtual ~UEdgeSetReader() {
  1230       for (typename MapReaders::iterator it = readers.begin(); 
  1231 	   it != readers.end(); ++it) {
  1232 	delete it->second;
  1233       }
  1234     }
  1235 
  1236   private:
  1237     UEdgeSetReader(const UEdgeSetReader&);
  1238     void operator=(const UEdgeSetReader&);
  1239 
  1240   public:
  1241 
  1242     /// \brief Add a new undirected edge map reader command for the reader.
  1243     ///
  1244     /// Add a new edge undirected map reader command for the reader.
  1245     template <typename Map>
  1246     UEdgeSetReader& readUEdgeMap(std::string name, Map& map) {
  1247       return _readMap<
  1248 	typename Traits::template Reader<typename Map::Value>, Map, 
  1249 	typename _reader_bits::Arg<Map>::Type>(name, map);
  1250     }
  1251 
  1252     template <typename Map>
  1253     UEdgeSetReader& readUEdgeMap(std::string name, const Map& map) {
  1254       return _readMap<
  1255 	typename Traits::template Reader<typename Map::Value>, Map, 
  1256 	typename _reader_bits::Arg<Map>::Type>(name, map);
  1257     }
  1258 
  1259     /// \brief Add a new undirected edge map reader command for the reader.
  1260     ///
  1261     /// Add a new edge undirected map reader command for the reader.
  1262     template <typename Reader, typename Map>
  1263     UEdgeSetReader& readUEdgeMap(std::string name, Map& map, 
  1264 					 const Reader& reader = Reader()) {
  1265       return _readMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
  1266 	(name, map, reader);
  1267     }
  1268 
  1269     template <typename Reader, typename Map>
  1270     UEdgeSetReader& readUEdgeMap(std::string name, const Map& map, 
  1271 					 const Reader& reader = Reader()) {
  1272       return _readMap<Reader, Map, typename _reader_bits::Arg<Map>::Type >
  1273 	(name, map, reader);
  1274     }
  1275 
  1276   private:
  1277 
  1278     template <typename Reader, typename Map, typename MapParameter>
  1279     UEdgeSetReader& _readMap(std::string name, MapParameter map,
  1280 				 const Reader& reader = Reader()) {
  1281       checkConcept<concept::WriteMap<UEdge, typename Map::Value>, Map>();
  1282       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
  1283       if (readers.find(name) != readers.end()) {
  1284 	ErrorMessage msg;
  1285 	msg << "Multiple read rule for edge map: " << name;
  1286 	throw IOParameterError(msg.message());
  1287       }
  1288       readers.insert(
  1289 	make_pair(name, new _reader_bits::
  1290 		  MapReader<UEdge, Map, Reader>(map, reader)));
  1291       return *this;
  1292     }
  1293 
  1294   public:
  1295 
  1296     /// \brief Add a new undirected edge map skipper command for the reader.
  1297     ///
  1298     /// Add a new undirected edge map skipper command for the reader.
  1299     template <typename Reader>
  1300     UEdgeSetReader& skipUEdgeMap(std::string name, 
  1301 					 const Reader& reader = Reader()) {
  1302       if (readers.find(name) != readers.end()) {
  1303 	ErrorMessage msg;
  1304 	msg << "Multiple read rule for node map: " << name;
  1305 	throw IOParameterError(msg.message());
  1306       }
  1307       readers.insert(make_pair(name, new _reader_bits::
  1308 			       SkipReader<UEdge, Reader>(reader)));
  1309       return *this;
  1310     }
  1311 
  1312     /// \brief Add a new directed edge map reader command for the reader.
  1313     ///
  1314     /// Add a new directed edge map reader command for the reader.
  1315     template <typename Map>
  1316     UEdgeSetReader& readEdgeMap(std::string name, Map& map) {
  1317       return _readDirMap<
  1318 	typename Traits::template Reader<typename Map::Value>, Map,
  1319 	typename _reader_bits::Arg<Map>::Type>(name, map);
  1320     }
  1321 
  1322     template <typename Map>
  1323     UEdgeSetReader& readEdgeMap(std::string name, const Map& map) {
  1324       return _readDirMap<
  1325 	typename Traits::template Reader<typename Map::Value>, Map,
  1326 	typename _reader_bits::Arg<Map>::Type>(name, map);
  1327     }
  1328 
  1329     /// \brief Add a new directed edge map reader command for the reader.
  1330     ///
  1331     /// Add a new directed edge map reader command for the reader.
  1332     template <typename Reader, typename Map>
  1333     UEdgeSetReader& readEdgeMap(std::string name, Map& map, 
  1334 				    const Reader& reader = Reader()) {
  1335       return _readDirMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
  1336 	(name, map, reader);
  1337     }
  1338 
  1339     template <typename Reader, typename Map>
  1340     UEdgeSetReader& readEdgeMap(std::string name, const Map& map, 
  1341 				    const Reader& reader = Reader()) {
  1342       return _readDirMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
  1343 	(name, map, reader);
  1344     }
  1345 
  1346   private:
  1347 
  1348     template <typename Reader, typename Map, typename MapParameter>
  1349     UEdgeSetReader& _readDirMap(std::string name, MapParameter map,
  1350 				    const Reader& reader = Reader()) { 
  1351       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
  1352       checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
  1353       readMap("+" + name, 
  1354 	      _reader_bits::forwardComposeMap(graph, map), reader);
  1355       readMap("-" + name, 
  1356 	      _reader_bits::backwardComposeMap(graph, map), reader);
  1357       return *this;      
  1358     }
  1359 
  1360   public:
  1361 
  1362     /// \brief Add a new directed edge map skipper command for the reader.
  1363     ///
  1364     /// Add a new directed edge map skipper command for the reader.
  1365     template <typename Reader>
  1366     UEdgeSetReader& skipEdgeMap(std::string name, 
  1367 				    const Reader& reader = Reader()) {
  1368       skipMap("+" + name, reader);
  1369       skipMap("-" + name, reader);
  1370       return *this;
  1371     }
  1372 
  1373   protected:
  1374 
  1375     /// \brief Gives back true when the SectionReader can process 
  1376     /// the section with the given header line.
  1377     ///
  1378     /// It gives back true when the header line starts with \c \@uedgeset,
  1379     /// and the header line's name and the edgeset's name are the same.
  1380     virtual bool header(const std::string& line) {
  1381       std::istringstream ls(line);
  1382       std::string command;
  1383       std::string id;
  1384       ls >> command >> name;
  1385       return command == "@uedgeset" && name == id;
  1386     }
  1387 
  1388     /// \brief Reader function of the section.
  1389     ///
  1390     /// It reads the content of the section.
  1391     virtual void read(std::istream& is) {
  1392       if (!nodeLabelReader->isLabelReader()) {
  1393 	throw DataFormatError("Cannot find nodeset or label map");
  1394       }
  1395       std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
  1396       std::string line;
  1397 
  1398       getline(is, line);
  1399       std::istringstream ls(line);	
  1400       std::string id;
  1401       while (ls >> id) {
  1402 	typename MapReaders::iterator it = readers.find(id);
  1403 	if (it != readers.end()) {
  1404 	  index.push_back(it->second);
  1405 	  it->second->touch();
  1406 	} else {
  1407 	  index.push_back(&skipper);
  1408 	}
  1409 	if (id == "label" || (id =="id" && inverter.get() == 0)) {
  1410 	  inverter.reset(index.back()->getInverter());
  1411 	  index.back() = inverter.get();
  1412 	}
  1413       }
  1414       for (typename MapReaders::iterator it = readers.begin();
  1415 	   it != readers.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       while (getline(is, line)) {	
  1423 	std::istringstream ls(line);
  1424 	Node from = nodeLabelReader->read(ls);
  1425 	Node to = nodeLabelReader->read(ls);
  1426 	UEdge edge = graph.addEdge(from, to);
  1427 	for (int i = 0; i < (int)index.size(); ++i) {
  1428 	  index[i]->read(ls, edge);
  1429 	}
  1430       }
  1431     }
  1432 
  1433   public:
  1434 
  1435     /// \brief Returns true if the edgeset can give back the edge by its label.
  1436     ///
  1437     /// Returns true if the edgeset can give back the undirected edge by its 
  1438     /// id. It is possible only if an "label" named map was read.
  1439     bool isLabelReader() const {
  1440       return inverter.get() != 0;
  1441     }
  1442 
  1443     /// \brief Gives back the undirected edge by its label.
  1444     ///
  1445     /// It reads an id from the stream and gives back which undirected edge 
  1446     /// belongs to it. It is possible only if there was read an "label" named map.
  1447     void readLabel(std::istream& is, UEdge& uEdge) const {
  1448       uEdge = inverter->read(is);
  1449     } 
  1450 
  1451     /// \brief Gives back the directed edge by its label.
  1452     ///
  1453     /// It reads an id from the stream and gives back which directed edge 
  1454     /// belongs to it. The directed edge id is the \c '+' or \c '-' character
  1455     /// and the undirected edge id. It is possible only if there was read 
  1456     /// an "label" named map.
  1457     void readLabel(std::istream& is, Edge& edge) const {
  1458       char c;
  1459       is >> c;
  1460       UEdge uEdge = inverter->read(is);
  1461       if (c == '+') {
  1462 	edge = graph.direct(uEdge, true);
  1463       } else if (c == '-') {
  1464         edge = graph.direct(uEdge, false);
  1465       } else {
  1466 	throw DataFormatError("Wrong id format for edge "
  1467 			      "in undirected edgeset");
  1468       }
  1469     } 
  1470 
  1471   private:
  1472 
  1473     typedef std::map<std::string, 
  1474 		     _reader_bits::MapReaderBase<UEdge>*> MapReaders;
  1475     MapReaders readers;
  1476    
  1477     Graph& graph;   
  1478     std::string name;
  1479     _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
  1480 
  1481     std::auto_ptr<_reader_bits::MapInverterBase<UEdge> > inverter;
  1482     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
  1483   };
  1484 
  1485   /// \ingroup io_group
  1486   /// \brief SectionReader for reading labeled nodes.
  1487   ///
  1488   /// The nodes section's header line is \c \@nodes \c nodes_name, but the
  1489   /// \c nodes_name may be empty.
  1490   ///
  1491   /// Each line in the section contains the name of the node 
  1492   /// and then the node id. 
  1493   ///
  1494   /// \relates LemonReader
  1495   template <typename _Graph>
  1496   class NodeReader : public LemonReader::SectionReader {
  1497     typedef LemonReader::SectionReader Parent;
  1498     typedef _Graph Graph;
  1499     typedef typename Graph::Node Node;
  1500   public:
  1501     
  1502     /// \brief Constructor.
  1503     ///
  1504     /// Constructor for NodeReader. It creates the NodeReader and
  1505     /// attach it into the given LemonReader. It will use the given
  1506     /// node id reader to give back the nodes. The reader will read the 
  1507     /// section only if the \c _name and the \c nodes_name are the same. 
  1508     template <typename _LabelReader>
  1509     NodeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  1510 	       const std::string& _name = std::string()) 
  1511       : Parent(_reader), name(_name) {
  1512       checkConcept<_reader_bits::ItemLabelReader<Node>, _LabelReader>();
  1513       nodeLabelReader.reset(new _reader_bits::
  1514 			 LabelReader<Node, _LabelReader>(_labelReader));
  1515     }
  1516 
  1517     /// \brief Destructor.
  1518     ///
  1519     /// Destructor for NodeReader.
  1520     virtual ~NodeReader() {}
  1521 
  1522   private:
  1523     NodeReader(const NodeReader&);
  1524     void operator=(const NodeReader&);
  1525 
  1526   public:
  1527 
  1528     /// \brief Add a node reader command for the NodeReader.
  1529     ///
  1530     /// Add a node reader command for the NodeReader.
  1531     void readNode(const std::string& name, Node& item) {
  1532       if (readers.find(name) != readers.end()) {
  1533 	ErrorMessage msg;
  1534 	msg << "Multiple read rule for node: " << name;
  1535 	throw IOParameterError(msg.message());
  1536       }
  1537       readers.insert(make_pair(name, _reader_bits::ItemStore<Node>(item)));
  1538     }
  1539 
  1540   protected:
  1541 
  1542     /// \brief Gives back true when the SectionReader can process 
  1543     /// the section with the given header line.
  1544     ///
  1545     /// It gives back true when the header line start with \c \@nodes,
  1546     /// and the header line's name and the reader's name are the same.
  1547     virtual bool header(const std::string& line) {
  1548       std::istringstream ls(line);
  1549       std::string command;
  1550       std::string id;
  1551       ls >> command >> name;
  1552       return command == "@nodes" && name == id;
  1553     }
  1554 
  1555     /// \brief Reader function of the section.
  1556     ///
  1557     /// It reads the content of the section.
  1558     virtual void read(std::istream& is) {
  1559       if (!nodeLabelReader->isLabelReader()) {
  1560 	throw DataFormatError("Cannot find nodeset or label map");
  1561       }
  1562       std::string line;
  1563       while (getline(is, line)) {
  1564 	std::istringstream ls(line);
  1565 	std::string id;
  1566 	ls >> id;
  1567 	typename NodeReaders::iterator it = readers.find(id);
  1568 	if (it != readers.end()) {
  1569 	  it->second.read(nodeLabelReader->read(ls));
  1570 	  it->second.touch();
  1571 	}	
  1572       }
  1573       for (typename NodeReaders::iterator it = readers.begin();
  1574 	   it != readers.end(); ++it) {
  1575 	if (!it->second.touched()) {
  1576 	  ErrorMessage msg;
  1577 	  msg << "Node not found in file: " << it->first;
  1578 	  throw IOParameterError(msg.message());
  1579 	}
  1580       }
  1581     }
  1582     
  1583   private:
  1584 
  1585     std::string name;
  1586 
  1587     typedef std::map<std::string, _reader_bits::ItemStore<Node> > NodeReaders;
  1588     NodeReaders readers;
  1589     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
  1590   };
  1591 
  1592   /// \ingroup io_group
  1593   /// \brief SectionReader for reading labeled edges.
  1594   ///
  1595   /// The edges section's header line is \c \@edges \c edges_name, but the
  1596   /// \c edges_name may be empty.
  1597   ///
  1598   /// Each line in the section contains the name of the edge 
  1599   /// and then the edge id. 
  1600   ///
  1601   /// \relates LemonReader
  1602   template <typename _Graph>
  1603   class EdgeReader : public LemonReader::SectionReader {
  1604     typedef LemonReader::SectionReader Parent;
  1605     typedef _Graph Graph;
  1606     typedef typename Graph::Edge Edge;
  1607   public:
  1608     
  1609     /// \brief Constructor.
  1610     ///
  1611     /// Constructor for EdgeReader. It creates the EdgeReader and
  1612     /// attach it into the given LemonReader. It will use the given
  1613     /// edge id reader to give back the edges. The reader will read the 
  1614     /// section only if the \c _name and the \c edges_name are the same. 
  1615     template <typename _LabelReader>
  1616     EdgeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  1617 	       const std::string& _name = std::string()) 
  1618       : Parent(_reader), name(_name) {
  1619       checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
  1620       edgeLabelReader.reset(new _reader_bits::
  1621 			 LabelReader<Edge, _LabelReader>(_labelReader));
  1622     }
  1623 
  1624     /// \brief Destructor.
  1625     ///
  1626     /// Destructor for EdgeReader.
  1627     virtual ~EdgeReader() {}
  1628   private:
  1629     EdgeReader(const EdgeReader&);
  1630     void operator=(const EdgeReader&);
  1631 
  1632   public:
  1633 
  1634     /// \brief Add an edge reader command for the EdgeReader.
  1635     ///
  1636     /// Add an edge reader command for the EdgeReader.
  1637     void readEdge(const std::string& name, Edge& item) {
  1638       if (readers.find(name) != readers.end()) {
  1639 	ErrorMessage msg;
  1640 	msg << "Multiple read rule for edge: " << name;
  1641 	throw IOParameterError(msg.message());
  1642       }
  1643       readers.insert(make_pair(name, _reader_bits::ItemStore<Edge>(item)));
  1644     }
  1645 
  1646   protected:
  1647 
  1648     /// \brief Gives back true when the SectionReader can process 
  1649     /// the section with the given header line.
  1650     ///
  1651     /// It gives back true when the header line start with \c \@edges,
  1652     /// and the header line's name and the reader's name are the same.
  1653     virtual bool header(const std::string& line) {
  1654       std::istringstream ls(line);
  1655       std::string command;
  1656       std::string id;
  1657       ls >> command >> name;
  1658       return command == "@edges" && name == id;
  1659     }
  1660 
  1661     /// \brief Reader function of the section.
  1662     ///
  1663     /// It reads the content of the section.
  1664     virtual void read(std::istream& is) {
  1665       if (!edgeLabelReader->isLabelReader()) {
  1666 	throw DataFormatError("Cannot find edgeset or label map");
  1667       }
  1668       std::string line;
  1669       while (getline(is, line)) {
  1670 	std::istringstream ls(line);
  1671 	std::string id;
  1672 	ls >> id;
  1673 	typename EdgeReaders::iterator it = readers.find(id);
  1674 	if (it != readers.end()) {
  1675 	  it->second.read(edgeLabelReader->read(ls));
  1676 	  it->second.touch();
  1677 	}	
  1678       }
  1679       for (typename EdgeReaders::iterator it = readers.begin();
  1680 	   it != readers.end(); ++it) {
  1681 	if (!it->second.touched()) {
  1682 	  ErrorMessage msg;
  1683 	  msg << "Edge not found in file: " << it->first;
  1684 	  throw IOParameterError(msg.message());
  1685 	}
  1686       }
  1687     }
  1688     
  1689   private:
  1690 
  1691     std::string name;
  1692 
  1693     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  1694     EdgeReaders readers;
  1695     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
  1696   };
  1697 
  1698   /// \ingroup io_group
  1699   /// \brief SectionReader for reading labeled undirected edges.
  1700   ///
  1701   /// The undirected edges section's header line is \c \@uedges 
  1702   /// \c uedges_name, but the \c uedges_name may be empty.
  1703   ///
  1704   /// Each line in the section contains the name of the undirected edge 
  1705   /// and then the undirected edge id. 
  1706   ///
  1707   /// \relates LemonReader
  1708   template <typename _Graph>
  1709   class UEdgeReader : public LemonReader::SectionReader {
  1710     typedef LemonReader::SectionReader Parent;
  1711     typedef _Graph Graph;
  1712     typedef typename Graph::Edge Edge;
  1713     typedef typename Graph::UEdge UEdge;
  1714   public:
  1715     
  1716     /// \brief Constructor.
  1717     ///
  1718     /// Constructor for UEdgeReader. It creates the UEdgeReader and
  1719     /// attach it into the given LemonReader. It will use the given
  1720     /// undirected edge id reader to give back the edges. The reader will 
  1721     /// read the section only if the \c _name and the \c uedges_name are 
  1722     /// the same. 
  1723     template <typename _LabelReader>
  1724     UEdgeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  1725 	       const std::string& _name = std::string()) 
  1726       : Parent(_reader), name(_name) {
  1727       checkConcept<_reader_bits::ItemLabelReader<UEdge>, _LabelReader>();
  1728       checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
  1729       uEdgeLabelReader.reset(new _reader_bits::
  1730 			      LabelReader<UEdge, _LabelReader>(_labelReader));
  1731       edgeLabelReader.reset(new _reader_bits::
  1732 			 LabelReader<Edge, _LabelReader>(_labelReader));
  1733     }
  1734 
  1735     /// \brief Destructor.
  1736     ///
  1737     /// Destructor for UEdgeReader.
  1738     virtual ~UEdgeReader() {}
  1739   private:
  1740     UEdgeReader(const UEdgeReader&);
  1741     void operator=(const UEdgeReader&);
  1742 
  1743   public:
  1744 
  1745     /// \brief Add an undirected edge reader command for the UEdgeReader.
  1746     ///
  1747     /// Add an undirected edge reader command for the UEdgeReader.
  1748     void readUEdge(const std::string& name, UEdge& item) {
  1749       if (uEdgeReaders.find(name) != uEdgeReaders.end()) {
  1750 	ErrorMessage msg;
  1751 	msg << "Multiple read rule for undirected edge: " << name;
  1752 	throw IOParameterError(msg.message());
  1753       }
  1754       uEdgeReaders.insert(make_pair(name, _reader_bits::
  1755 					ItemStore<UEdge>(item)));
  1756     }
  1757 
  1758     /// \brief Add an edge reader command for the UEdgeReader.
  1759     ///
  1760     /// Add an edge reader command for the UEdgeReader.
  1761     void readEdge(const std::string& name, Edge& item) {
  1762       if (edgeReaders.find(name) != edgeReaders.end()) {
  1763 	ErrorMessage msg;
  1764 	msg << "Multiple read rule for edge: " << name;
  1765 	throw IOParameterError(msg.message());
  1766       }
  1767       edgeReaders.insert(make_pair(name, _reader_bits::ItemStore<Edge>(item)));
  1768     }
  1769 
  1770   protected:
  1771 
  1772     /// \brief Gives back true when the SectionReader can process 
  1773     /// the section with the given header line.
  1774     ///
  1775     /// It gives back true when the header line start with \c \@edges,
  1776     /// and the header line's name and the reader's name are the same.
  1777     virtual bool header(const std::string& line) {
  1778       std::istringstream ls(line);
  1779       std::string command;
  1780       std::string id;
  1781       ls >> command >> name;
  1782       return command == "@uedges" && name == id;
  1783     }
  1784 
  1785     /// \brief Reader function of the section.
  1786     ///
  1787     /// It reads the content of the section.
  1788     virtual void read(std::istream& is) {
  1789       if (!edgeLabelReader->isLabelReader()) {
  1790 	throw DataFormatError("Cannot find undirected edgeset or label map");
  1791       }
  1792       if (!uEdgeLabelReader->isLabelReader()) {
  1793 	throw DataFormatError("Cannot find undirected edgeset or label map");
  1794       }
  1795       std::string line;
  1796       while (getline(is, line)) {
  1797 	std::istringstream ls(line);
  1798 	std::string id;
  1799 	ls >> id;
  1800 	{
  1801 	  typename UEdgeReaders::iterator it = uEdgeReaders.find(id);
  1802 	  if (it != uEdgeReaders.end()) {
  1803 	    it->second.read(uEdgeLabelReader->read(ls));
  1804 	    it->second.touch();
  1805 	    continue;
  1806 	  }	
  1807 	} {
  1808 	  typename EdgeReaders::iterator it = edgeReaders.find(id);
  1809 	  if (it != edgeReaders.end()) {
  1810 	    it->second.read(edgeLabelReader->read(ls));
  1811 	    it->second.touch();
  1812 	    continue;
  1813 	  }	
  1814 	}
  1815       }
  1816       for (typename EdgeReaders::iterator it = edgeReaders.begin();
  1817 	   it != edgeReaders.end(); ++it) {
  1818 	if (!it->second.touched()) {
  1819 	  ErrorMessage msg;
  1820 	  msg << "Edge not found in file: " << it->first;
  1821 	  throw IOParameterError(msg.message());
  1822 	}
  1823       }
  1824       for (typename UEdgeReaders::iterator it = uEdgeReaders.begin();
  1825 	   it != uEdgeReaders.end(); ++it) {
  1826 	if (!it->second.touched()) {
  1827 	  ErrorMessage msg;
  1828 	  msg << "UEdge not found in file: " << it->first;
  1829 	  throw IOParameterError(msg.message());
  1830 	}
  1831       }
  1832     }
  1833     
  1834   private:
  1835 
  1836     std::string name;
  1837 
  1838     typedef std::map<std::string, 
  1839 		     _reader_bits::ItemStore<UEdge> > UEdgeReaders;
  1840     UEdgeReaders uEdgeReaders;
  1841     std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uEdgeLabelReader;
  1842 
  1843     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  1844     EdgeReaders edgeReaders;
  1845     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
  1846   };
  1847 
  1848   /// \ingroup io_group
  1849   /// \brief SectionReader for attributes.
  1850   ///
  1851   /// The lemon format can store multiple attribute set. Each set has
  1852   /// the header line \c \@attributes \c attributeset_name, but the 
  1853   /// attributeset_name may be empty.
  1854   ///
  1855   /// The attributeset section contains several lines. Each of them starts
  1856   /// with an attribute and then a the value for the id.
  1857   ///
  1858   /// \relates LemonReader
  1859   template <typename _Traits = DefaultReaderTraits>
  1860   class AttributeReader : public LemonReader::SectionReader {
  1861     typedef LemonReader::SectionReader Parent;
  1862     typedef _Traits Traits; 
  1863   public:
  1864     /// \brief Constructor.
  1865     ///
  1866     /// Constructor for AttributeReader. It creates the AttributeReader and
  1867     /// attach it into the given LemonReader. The reader process a section
  1868     /// only if the \c section_name and the \c _name are the same.
  1869     AttributeReader(LemonReader& _reader, 
  1870 		    const std::string& _name = std::string()) 
  1871       : Parent(_reader), name(_name) {}
  1872 
  1873     /// \brief Destructor.
  1874     ///
  1875     /// Destructor for AttributeReader.
  1876     virtual ~AttributeReader() {
  1877       for (typename Readers::iterator it = readers.begin(); 
  1878 	   it != readers.end(); ++it) {
  1879 	delete it->second;
  1880       }
  1881     }
  1882 
  1883   private:
  1884     AttributeReader(const AttributeReader&);
  1885     void operator=(AttributeReader&);
  1886 
  1887   public:
  1888     /// \brief Add an attribute reader command for the reader.
  1889     ///
  1890     /// Add an attribute reader command for the reader.
  1891     template <typename Value>
  1892     AttributeReader& readAttribute(const std::string& id, Value& value) {
  1893       return readAttribute<typename Traits::template Reader<Value> >
  1894 	(id, value);
  1895     }
  1896 
  1897     /// \brief Add an attribute reader command for the reader.
  1898     ///
  1899     /// Add an attribute reader command for the reader.
  1900     template <typename Reader, typename Value>
  1901     AttributeReader& readAttribute(const std::string& name, Value& value,
  1902 				   const Reader& reader = Reader()) {
  1903       checkConcept<_reader_bits::ItemReader<Value>, Reader>();
  1904       if (readers.find(name) != readers.end()) {
  1905 	ErrorMessage msg;
  1906 	msg << "Multiple read rule for attribute: " << name;
  1907 	throw IOParameterError(msg.message());
  1908       }
  1909       readers.insert(make_pair(name, new _reader_bits::
  1910 			       ValueReader<Value, Reader>(value, reader)));
  1911       return *this;
  1912     }
  1913 
  1914   protected:
  1915 
  1916     /// \brief Gives back true when the SectionReader can process 
  1917     /// the section with the given header line.
  1918     ///
  1919     /// It gives back true when the header line start with \c \@attributes,
  1920     /// and the header line's id and the attributeset's id are the same.
  1921     bool header(const std::string& line) {
  1922       std::istringstream ls(line);
  1923       std::string command;
  1924       std::string id;
  1925       ls >> command >> name;
  1926       return command == "@attributes" && name == id;
  1927     }
  1928 
  1929     /// \brief Reader function of the section.
  1930     ///
  1931     /// It reads the content of the section.
  1932     void read(std::istream& is) {
  1933       std::string line;
  1934       while (getline(is, line)) {
  1935 	std::istringstream ls(line);
  1936 	std::string id;
  1937 	ls >> id;
  1938 	typename Readers::iterator it = readers.find(id);
  1939 	if (it != readers.end()) {
  1940 	  it->second->read(ls);
  1941  	  it->second->touch();
  1942 	}
  1943       }
  1944       for (typename Readers::iterator it = readers.begin();
  1945 	   it != readers.end(); ++it) {
  1946 	if (!it->second->touched()) {
  1947 	  ErrorMessage msg;
  1948 	  msg << "Attribute not found in file: " << it->first;
  1949 	  throw IOParameterError(msg.message());
  1950 	}	
  1951       }
  1952     }    
  1953 
  1954   private:
  1955     std::string name;
  1956 
  1957     typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers;
  1958     Readers readers;  
  1959   };
  1960 
  1961   /// \ingroup io_group
  1962   /// \brief SectionReader for retrieve what is in the file.
  1963   ///
  1964   /// SectionReader for retrieve what is in the file. If you want
  1965   /// to know which sections, maps and items are in the file
  1966   /// use the next code:
  1967   ///\code
  1968   /// LemonReader reader("input.lgf");
  1969   /// ContentReader content(reader);
  1970   /// reader.run();
  1971   ///\endcode
  1972   class ContentReader : public LemonReader::SectionReader {
  1973     typedef LemonReader::SectionReader Parent;
  1974   public:
  1975     /// \brief Constructor.
  1976     ///
  1977     /// Constructor for
  1978     ContentReader(LemonReader& _reader) : Parent(_reader) {}
  1979 
  1980     /// \brief Desctructor.
  1981     ///
  1982     /// Desctructor.
  1983     virtual ~ContentReader() {}
  1984 
  1985     /// \brief Gives back how many nodesets are in the file.
  1986     ///
  1987     /// Gives back how many nodesets are in the file.
  1988     int nodeSetNum() const {
  1989       return nodesets.size();
  1990     }
  1991 
  1992     /// \brief Gives back the name of nodeset on the indiced position.
  1993     ///
  1994     /// Gives back the name of nodeset on the indiced position.
  1995     std::string nodeSetName(int index) const {
  1996       return nodesets[index].name;
  1997     }
  1998 
  1999     /// \brief Gives back the map names of nodeset on the indiced position.
  2000     ///
  2001     /// Gives back the map names of nodeset on the indiced position.
  2002     const std::vector<std::string>& nodeSetMaps(int index) const {
  2003       return nodesets[index].items;
  2004     }
  2005 
  2006     /// \brief Gives back how many edgesets are in the file.
  2007     ///
  2008     /// Gives back how many edgesets are in the file.
  2009     int edgeSetNum() const {
  2010       return edgesets.size();
  2011     }
  2012 
  2013     /// \brief Gives back the name of edgeset on the indiced position.
  2014     ///
  2015     /// Gives back the name of edgeset on the indiced position.
  2016     std::string edgeSetName(int index) const {
  2017       return edgesets[index].name;
  2018     }
  2019 
  2020     /// \brief Gives back the map names of edgeset on the indiced position.
  2021     ///
  2022     /// Gives back the map names of edgeset on the indiced position.
  2023     const std::vector<std::string>& edgeSetMaps(int index) const {
  2024       return edgesets[index].items;
  2025     }
  2026 
  2027     /// \brief Gives back how many undirected edgesets are in the file.
  2028     ///
  2029     /// Gives back how many undirected edgesets are in the file.
  2030     int uEdgeSetNum() const {
  2031       return uedgesets.size();
  2032     }
  2033 
  2034     /// \brief Gives back the name of undirected edgeset on the indiced 
  2035     /// position.
  2036     ///
  2037     /// Gives back the name of undirected edgeset on the indiced position.
  2038     std::string uEdgeSetName(int index) const {
  2039       return uedgesets[index].name;
  2040     }
  2041 
  2042     /// \brief Gives back the map names of undirected edgeset on the indiced 
  2043     /// position.
  2044     ///
  2045     /// Gives back the map names of undirected edgeset on the indiced position.
  2046     const std::vector<std::string>& uEdgeSetMaps(int index) const {
  2047       return uedgesets[index].items;
  2048     }
  2049 
  2050     /// \brief Gives back how many labeled nodes section are in the file.
  2051     ///
  2052     /// Gives back how many labeled nodes section are in the file.
  2053     int nodesNum() const {
  2054       return nodes.size();
  2055     }
  2056 
  2057     /// \brief Gives back the name of labeled nodes section on the indiced 
  2058     /// position.
  2059     ///
  2060     /// Gives back the name of labeled nodes section on the indiced position.
  2061     std::string nodesName(int index) const {
  2062       return nodes[index].name;
  2063     }
  2064 
  2065     /// \brief Gives back the names of the labeled nodes in the indiced 
  2066     /// section.
  2067     ///
  2068     /// Gives back the names of the labeled nodes in the indiced section.
  2069     const std::vector<std::string>& nodesItems(int index) const {
  2070       return nodes[index].items;
  2071     }
  2072 
  2073     /// \brief Gives back how many labeled edges section are in the file.
  2074     ///
  2075     /// Gives back how many labeled edges section are in the file.
  2076     int edgesNum() const {
  2077       return edges.size();
  2078     }
  2079 
  2080     /// \brief Gives back the name of labeled edges section on the indiced 
  2081     /// position.
  2082     ///
  2083     /// Gives back the name of labeled edges section on the indiced position.
  2084     std::string edgesName(int index) const {
  2085       return edges[index].name;
  2086     }
  2087 
  2088     /// \brief Gives back the names of the labeled edges in the indiced 
  2089     /// section.
  2090     ///
  2091     /// Gives back the names of the labeled edges in the indiced section.
  2092     const std::vector<std::string>& edgesItems(int index) const {
  2093       return edges[index].items;
  2094     }
  2095  
  2096     /// \brief Gives back how many labeled undirected edges section are 
  2097     /// in the file.
  2098     ///
  2099     /// Gives back how many labeled undirected edges section are in the file.
  2100     int uEdgesNum() const {
  2101       return uedges.size();
  2102     }
  2103 
  2104     /// \brief Gives back the name of labeled undirected edges section 
  2105     /// on the indiced position.
  2106     ///
  2107     /// Gives back the name of labeled undirected edges section on the 
  2108     /// indiced position.
  2109     std::string uEdgesName(int index) const {
  2110       return uedges[index].name;
  2111     }
  2112 
  2113     /// \brief Gives back the names of the labeled undirected edges in 
  2114     /// the indiced section.
  2115     ///
  2116     /// Gives back the names of the labeled undirected edges in the 
  2117     /// indiced section.
  2118     const std::vector<std::string>& uEdgesItems(int index) const {
  2119       return uedges[index].items;
  2120     }
  2121 
  2122  
  2123     /// \brief Gives back how many attributes section are in the file.
  2124     ///
  2125     /// Gives back how many attributes section are in the file.
  2126     int attributesNum() const {
  2127       return attributes.size();
  2128     }
  2129 
  2130     /// \brief Gives back the name of attributes section on the indiced 
  2131     /// position.
  2132     ///
  2133     /// Gives back the name of attributes section on the indiced position.
  2134     std::string attributesName(int index) const {
  2135       return attributes[index].name;
  2136     }
  2137 
  2138     /// \brief Gives back the names of the attributes in the indiced section.
  2139     ///
  2140     /// Gives back the names of the attributes in the indiced section.
  2141     const std::vector<std::string>& attributesItems(int index) const {
  2142       return attributes[index].items;
  2143     }
  2144 
  2145     const std::vector<std::string>& otherSections() const {
  2146       return sections;
  2147     }
  2148 
  2149   protected:
  2150     
  2151     /// \brief Gives back true when the SectionReader can process 
  2152     /// the section with the given header line.
  2153     ///
  2154     /// It gives back true when the section is common section.
  2155     bool header(const std::string& line) {
  2156       std::istringstream ls(line);
  2157       std::string command, name;
  2158       ls >> command >> name;
  2159       if (command == "@nodeset") {
  2160 	current = command;
  2161 	nodesets.push_back(SectionInfo(name));
  2162       } else if (command == "@edgeset") {
  2163 	current = command;
  2164 	edgesets.push_back(SectionInfo(name));
  2165       } else if (command == "@uedgeset") {
  2166 	current = command;
  2167 	uedgesets.push_back(SectionInfo(name));
  2168       } else if (command == "@nodes") {
  2169 	current = command;
  2170 	nodes.push_back(SectionInfo(name));
  2171       } else if (command == "@edges") {
  2172 	current = command;
  2173 	edges.push_back(SectionInfo(name));
  2174       } else if (command == "@uedges") {
  2175 	current = command;
  2176 	uedges.push_back(SectionInfo(name));
  2177       } else if (command == "@attributes") {
  2178 	current = command;
  2179 	attributes.push_back(SectionInfo(name));
  2180       } else {
  2181 	sections.push_back(line);
  2182 	return false;
  2183       }
  2184       return true;
  2185     }
  2186 
  2187     /// \brief Retrieve the items from various sections.
  2188     ///
  2189     /// Retrieve the items from various sections.
  2190     void read(std::istream& is) {
  2191       if (current == "@nodeset") {
  2192 	readMapNames(is, nodesets.back().items);
  2193       } else if (current == "@edgeset") {
  2194 	readMapNames(is, edgesets.back().items);
  2195       } else if (current == "@uedgeset") {
  2196 	readMapNames(is, uedgesets.back().items);
  2197       } else if (current == "@nodes") {
  2198 	readItemNames(is, nodes.back().items);
  2199       } else if (current == "@edges") {
  2200 	readItemNames(is, edges.back().items);
  2201       } else if (current == "@uedges") {
  2202 	readItemNames(is, uedges.back().items);
  2203       } else if (current == "@attributes") {
  2204 	readItemNames(is, attributes.back().items);
  2205       }
  2206     }    
  2207 
  2208   private:
  2209 
  2210     void readMapNames(std::istream& is, std::vector<std::string>& maps) {
  2211       std::string line, name;
  2212       std::getline(is, line);
  2213       std::istringstream ls(line);
  2214       while (ls >> name) {
  2215 	maps.push_back(name);
  2216       }
  2217       while (getline(is, line));
  2218     }
  2219 
  2220     void readItemNames(std::istream& is, std::vector<std::string>& maps) {
  2221       std::string line, name;
  2222       while (std::getline(is, line)) {
  2223 	std::istringstream ls(line);
  2224 	ls >> name;
  2225 	maps.push_back(name);
  2226       }
  2227     }
  2228 
  2229     struct SectionInfo {
  2230       std::string name;
  2231       std::vector<std::string> items;
  2232 
  2233       SectionInfo(const std::string& _name) : name(_name) {}
  2234     };
  2235 
  2236     std::vector<SectionInfo> nodesets;
  2237     std::vector<SectionInfo> edgesets;
  2238     std::vector<SectionInfo> uedgesets;
  2239 
  2240     std::vector<SectionInfo> nodes;
  2241     std::vector<SectionInfo> edges;
  2242     std::vector<SectionInfo> uedges;
  2243 
  2244     std::vector<SectionInfo> attributes;
  2245 
  2246     std::vector<std::string> sections;
  2247 
  2248     std::string current;
  2249 
  2250   };
  2251 
  2252 }
  2253 #endif