lemon/lemon_reader.h
author deba
Wed, 01 Mar 2006 10:25:30 +0000
changeset 1991 d7442141d9ef
parent 1946 17eb3eaad9f8
child 1993 2115143eceea
permissions -rw-r--r--
The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.

The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.

The ResGraphAdaptor is based on this composition.
     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