src/lemon/lemon_reader.h
changeset 1435 8e85e6bbefdf
parent 1434 d8475431bbbb
child 1436 e0beb94d08bf
     1.1 --- a/src/lemon/lemon_reader.h	Sat May 21 21:04:57 2005 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,1977 +0,0 @@
     1.4 -/* -*- C++ -*-
     1.5 - * src/lemon/lemon_reader.h - Part of LEMON, a generic C++ optimization library
     1.6 - *
     1.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     1.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
     1.9 - *
    1.10 - * Permission to use, modify and distribute this software is granted
    1.11 - * provided that this copyright notice appears in all copies. For
    1.12 - * precise terms see the accompanying LICENSE file.
    1.13 - *
    1.14 - * This software is provided "AS IS" with no warranty of any kind,
    1.15 - * express or implied, and with no claim as to its suitability for any
    1.16 - * purpose.
    1.17 - *
    1.18 - */
    1.19 -
    1.20 -///\ingroup io_group
    1.21 -///\file
    1.22 -///\brief Lemon Format reader.
    1.23 -
    1.24 -
    1.25 -#ifndef LEMON_LEMON_READER_H
    1.26 -#define LEMON_LEMON_READER_H
    1.27 -
    1.28 -
    1.29 -#include <iostream>
    1.30 -#include <fstream>
    1.31 -#include <string>
    1.32 -#include <vector>
    1.33 -#include <algorithm>
    1.34 -#include <map>
    1.35 -#include <memory>
    1.36 -
    1.37 -#include <lemon/error.h>
    1.38 -#include <lemon/graph_utils.h>
    1.39 -#include <lemon/utility.h>
    1.40 -#include <lemon/bits/item_reader.h>
    1.41 -
    1.42 -
    1.43 -namespace lemon {
    1.44 -
    1.45 -  namespace _reader_bits {
    1.46 -  
    1.47 -    template <typename T>
    1.48 -    bool operator<(T, T) {
    1.49 -      throw DataFormatError("Id is not comparable");
    1.50 -    }
    1.51 -
    1.52 -    template <typename T>
    1.53 -    struct Less {
    1.54 -      bool operator()(const T& p, const T& q) const {
    1.55 -	return p < q;
    1.56 -      }
    1.57 -    };
    1.58 -
    1.59 -    template <typename M1, typename M2>
    1.60 -    class WriteComposeMap {
    1.61 -    public:
    1.62 -      typedef True NeedCopy;
    1.63 -      
    1.64 -      typedef typename M2::Key Key;
    1.65 -      typedef typename M1::Value Value;
    1.66 -
    1.67 -      WriteComposeMap(typename SmartParameter<M1>::Type _m1, const M2& _m2) 
    1.68 -	: m1(_m1), m2(_m2) {}
    1.69 -      
    1.70 -      void set(const Key& key, const Value& value) {
    1.71 -	m1.set(m2[key], value);
    1.72 -      }
    1.73 -
    1.74 -    private:
    1.75 -      
    1.76 -      typename SmartReference<M1>::Type m1;
    1.77 -      typename SmartConstReference<M2>::Type m2;
    1.78 -      
    1.79 -    };
    1.80 -
    1.81 -    template <typename M1, typename M2>
    1.82 -    WriteComposeMap<M1, M2> writeComposeMap(M1& m1, const M2& m2) {
    1.83 -      return WriteComposeMap<M1, M2>(m1, m2);
    1.84 -    }
    1.85 -
    1.86 -    template <typename M1, typename M2>
    1.87 -    WriteComposeMap<M1, M2> writeComposeMap(const M1& m1, const M2& m2) {
    1.88 -      return WriteComposeMap<M1, M2>(m1, m2);
    1.89 -    }
    1.90 -  
    1.91 -  }
    1.92 -
    1.93 -  /// \ingroup io_group
    1.94 -  /// \brief Lemon Format reader class.
    1.95 -  /// 
    1.96 -  /// The Lemon Format contains several sections. We do not want to
    1.97 -  /// determine what sections are in a lemon file we give only a framework
    1.98 -  /// to read a section oriented format.
    1.99 -  ///
   1.100 -  /// In the Lemon Format each section starts with a line contains a \c \@
   1.101 -  /// character on the first not white space position. This line is the
   1.102 -  /// header line of the section. Each next lines belong to this section
   1.103 -  /// while it does not starts with \c \@ character. This line can start a 
   1.104 -  /// new section or if it can close the file with the \c \@end line.
   1.105 -  /// The file format ignore the empty and comment lines. The line is
   1.106 -  /// comment line if it starts with a \c # character. 
   1.107 -  ///
   1.108 -  /// The framework provides an abstract LemonReader::SectionReader class
   1.109 -  /// what defines the interface of a SectionReader. The SectionReader
   1.110 -  /// has the \c header() member function what get a header line string and
   1.111 -  /// decides if it want to process the next section. Several SectionReaders
   1.112 -  /// can be attached to an LemonReader and the first attached what can
   1.113 -  /// process the section will be used. Its \c read() member will called
   1.114 -  /// with a stream contains the section. From this stream the empty and
   1.115 -  /// comment lines are filtered out.
   1.116 -  ///
   1.117 -  /// \relates GraphReader
   1.118 -  /// \relates NodeSetReader
   1.119 -  /// \relates EdgeSetReader
   1.120 -  /// \relates NodesReader
   1.121 -  /// \relates EdgesReader
   1.122 -  /// \relates AttributeReader
   1.123 -  class LemonReader {
   1.124 -  private:
   1.125 -    
   1.126 -    class FilterStreamBuf : public std::streambuf {
   1.127 -    public:
   1.128 -
   1.129 -      typedef std::streambuf Parent;
   1.130 -      typedef Parent::char_type char_type;
   1.131 -      FilterStreamBuf(std::istream& is, int& num) 
   1.132 -	: _is(is), _base(0), _eptr(0), 
   1.133 -	  _num(num), skip_state(after_endl) {}
   1.134 -
   1.135 -    protected:
   1.136 -
   1.137 -      enum skip_state_type {
   1.138 -	no_skip,
   1.139 -	after_endl,
   1.140 -	comment_line
   1.141 -      };
   1.142 -
   1.143 -      char_type small_buf[1];
   1.144 -
   1.145 -
   1.146 -      std::istream& _is;
   1.147 -
   1.148 -      char_type* _base;
   1.149 -      char_type* _eptr;
   1.150 -
   1.151 -      int& _num;
   1.152 -
   1.153 -      skip_state_type skip_state;
   1.154 -
   1.155 -
   1.156 -      char_type* base() { return _base; }
   1.157 -
   1.158 -      char_type* eptr() { return _eptr; }
   1.159 -
   1.160 -      int blen() { return _eptr - _base; }
   1.161 -
   1.162 -      void setb(char_type* buf, int len) {
   1.163 -	_base = buf;
   1.164 -	_eptr = buf + len;
   1.165 -      }
   1.166 -  
   1.167 -      virtual std::streambuf* setbuf(char *buf, int len) {
   1.168 -	if (base()) return 0;
   1.169 -	if (buf != 0 && len >= (int)sizeof(small_buf)) {
   1.170 -	  setb(buf, len);
   1.171 -	} else {
   1.172 -	  setb(small_buf, sizeof(small_buf));
   1.173 -	}
   1.174 -	setg(0, 0, 0);
   1.175 -	return this;
   1.176 -      }
   1.177 -
   1.178 -      bool put_char(char c) {
   1.179 -	switch (skip_state) {
   1.180 -	case no_skip:
   1.181 -	  switch (c) {
   1.182 -	  case '\n': 
   1.183 -	    skip_state = after_endl;
   1.184 -	    return true;
   1.185 -	  default:
   1.186 -	    return true;
   1.187 -	  }
   1.188 -	case after_endl:
   1.189 -	  switch (c) {
   1.190 -	  case '@':
   1.191 -	    return false;
   1.192 -	  case '\n': 
   1.193 -	    return false;
   1.194 -	  case '#':
   1.195 -	    skip_state = comment_line;
   1.196 -	    return false;
   1.197 -	  default:
   1.198 -	    if (!isspace(c)) {
   1.199 -	      skip_state = no_skip;
   1.200 -	      return true;
   1.201 -	    } else {
   1.202 -	      return false;
   1.203 -	    }
   1.204 -	  }
   1.205 -	  break;
   1.206 -	case comment_line:
   1.207 -	  switch (c) {
   1.208 -	  case '\n': 
   1.209 -	    skip_state = after_endl;
   1.210 -	    return false;
   1.211 -	  default:
   1.212 -	    return false;
   1.213 -	  }
   1.214 -	}
   1.215 -	return false;
   1.216 -      }
   1.217 -
   1.218 -      virtual int underflow() {
   1.219 -	char c;
   1.220 -	if (_is.read(&c, 1)) {
   1.221 -	  _is.putback(c);
   1.222 -	  if (c == '@') {
   1.223 -	    return EOF;
   1.224 -	  }
   1.225 -	} else {
   1.226 -	  return EOF;
   1.227 -	}
   1.228 -	char_type *ptr;
   1.229 -	for (ptr = base(); ptr != eptr(); ++ptr) {
   1.230 -	  if (_is.read(&c, 1)) {
   1.231 -	    if (c == '\n') ++_num;
   1.232 -	    if (put_char(c)) {
   1.233 -	      *ptr = c;
   1.234 -	    } else {
   1.235 -	      if (skip_state == after_endl && c == '@') {
   1.236 -		_is.putback('@');
   1.237 -		break;
   1.238 -	      }
   1.239 -	      --ptr;
   1.240 -	    }
   1.241 -	  } else {
   1.242 -	    break;
   1.243 -	  }
   1.244 -	}
   1.245 -	setg(base(), base(), ptr);
   1.246 -	return *base();
   1.247 -      }
   1.248 -
   1.249 -      virtual int sync() {
   1.250 -	return EOF;
   1.251 -      }
   1.252 -    };
   1.253 -
   1.254 -  public:
   1.255 -
   1.256 -    /// \brief Abstract base class for reading a section.
   1.257 -    ///
   1.258 -    /// This class has an \c header() member function what get a 
   1.259 -    /// header line string and decides if it want to process the next 
   1.260 -    /// section. Several SectionReaders can be attached to an LemonReader 
   1.261 -    /// and the first attached what can process the section will be used. 
   1.262 -    /// Its \c read() member will called with a stream contains the section. 
   1.263 -    /// From this stream the empty lines and comments are filtered out.
   1.264 -    class SectionReader {
   1.265 -      friend class LemonReader;
   1.266 -    protected:
   1.267 -      /// \brief Constructor for SectionReader.
   1.268 -      ///
   1.269 -      /// Constructor for SectionReader. It attach this reader to
   1.270 -      /// the given LemonReader.
   1.271 -      SectionReader(LemonReader& reader) {
   1.272 -	reader.attach(*this);
   1.273 -      }
   1.274 -
   1.275 -      /// \brief Gives back true when the SectionReader can process 
   1.276 -      /// the section with the given header line.
   1.277 -      ///
   1.278 -      /// It gives back true when the SectionReader can process
   1.279 -      /// the section with the given header line.
   1.280 -      virtual bool header(const std::string& line) = 0;
   1.281 -
   1.282 -      /// \brief Reader function of the section.
   1.283 -      ///
   1.284 -      /// It reads the content of the section.
   1.285 -      virtual void read(std::istream& is) = 0;
   1.286 -    };
   1.287 -
   1.288 -    /// \brief Constructor for LemonReader.
   1.289 -    ///
   1.290 -    /// Constructor for LemonReader which reads from the given stream.
   1.291 -    LemonReader(std::istream& _is) 
   1.292 -      : is(&_is), own_is(false) {}
   1.293 -
   1.294 -    /// \brief Constructor for LemonReader.
   1.295 -    ///
   1.296 -    /// Constructor for LemonReader which reads from the given file.
   1.297 -    LemonReader(const std::string& filename) 
   1.298 -      : is(0), own_is(true) {
   1.299 -      is = new std::ifstream(filename.c_str());
   1.300 -    }
   1.301 -
   1.302 -    /// \brief Desctructor for LemonReader.
   1.303 -    ///
   1.304 -    /// Desctructor for LemonReader.
   1.305 -    ~LemonReader() {
   1.306 -      if (own_is) {
   1.307 -	delete is;
   1.308 -      }
   1.309 -    }
   1.310 -
   1.311 -  private:
   1.312 -    LemonReader(const LemonReader&);
   1.313 -    void operator=(const LemonReader&);
   1.314 -
   1.315 -    void attach(SectionReader& reader) {
   1.316 -      readers.push_back(&reader);
   1.317 -    }
   1.318 -
   1.319 -  public:
   1.320 -    /// \brief Executes the LemonReader.
   1.321 -    /// 
   1.322 -    /// It executes the LemonReader.
   1.323 -    void run() {
   1.324 -      int line_num = 0;
   1.325 -      std::string line;
   1.326 -      try {
   1.327 -	while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
   1.328 -	  SectionReaders::iterator it;
   1.329 -	  for (it = readers.begin(); it != readers.end(); ++it) {
   1.330 -	    if ((*it)->header(line)) {
   1.331 -	      char buf[2048];
   1.332 -	      FilterStreamBuf buffer(*is, line_num);
   1.333 -	      buffer.pubsetbuf(buf, sizeof(buf));
   1.334 -	      std::istream is(&buffer);
   1.335 -	      (*it)->read(is);
   1.336 -	      break;
   1.337 -	    }
   1.338 -	  }
   1.339 -	}
   1.340 -      } catch (DataFormatError& error) {
   1.341 -	error.line(line_num);
   1.342 -	throw error;
   1.343 -      }	
   1.344 -    }
   1.345 -
   1.346 -
   1.347 -  private:
   1.348 -
   1.349 -    std::istream* is;
   1.350 -    bool own_is;
   1.351 -
   1.352 -    typedef std::vector<SectionReader*> SectionReaders;
   1.353 -    SectionReaders readers;
   1.354 -
   1.355 -  };
   1.356 -
   1.357 -  /// \brief Helper class for implementing the common SectionReaders.
   1.358 -  ///
   1.359 -  /// Helper class for implementing the common SectionReaders.
   1.360 -  class CommonSectionReaderBase : public LemonReader::SectionReader {
   1.361 -    typedef LemonReader::SectionReader Parent;
   1.362 -  protected:
   1.363 -    
   1.364 -    /// \brief Constructor for CommonSectionReaderBase.
   1.365 -    ///
   1.366 -    /// Constructor for CommonSectionReaderBase. It attach this reader to
   1.367 -    /// the given LemonReader.
   1.368 -    CommonSectionReaderBase(LemonReader& _reader) 
   1.369 -      : Parent(_reader) {}
   1.370 -
   1.371 -    template <typename _Item>
   1.372 -    class ReaderBase;
   1.373 -    
   1.374 -    template <typename _Item>
   1.375 -    class InverterBase : public ReaderBase<_Item> {
   1.376 -    public:
   1.377 -      typedef _Item Item;
   1.378 -      virtual void read(std::istream&, const Item&) = 0;
   1.379 -      virtual Item read(std::istream&) const = 0;
   1.380 -
   1.381 -      virtual InverterBase<_Item>* getInverter() {
   1.382 -	return this;
   1.383 -      }
   1.384 -    };
   1.385 -
   1.386 -    template <typename _Item, typename _Map, typename _Reader>
   1.387 -    class MapReaderInverter : public InverterBase<_Item> {
   1.388 -    public:
   1.389 -      typedef _Item Item;
   1.390 -      typedef _Reader Reader;
   1.391 -      typedef typename Reader::Value Value;
   1.392 -      typedef _Map Map;
   1.393 -      typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
   1.394 -
   1.395 -      typename SmartReference<Map>::Type map;
   1.396 -      Reader reader;
   1.397 -      Inverse inverse;
   1.398 -
   1.399 -      MapReaderInverter(typename SmartParameter<Map>::Type _map,
   1.400 -			const Reader& _reader) 
   1.401 -	: map(_map), reader(_reader) {}
   1.402 -
   1.403 -      virtual ~MapReaderInverter() {}
   1.404 -
   1.405 -      virtual void read(std::istream& is, const Item& item) {
   1.406 -	Value value;
   1.407 -	reader.read(is, value);
   1.408 -	map.set(item, value);
   1.409 -	typename Inverse::iterator it = inverse.find(value);
   1.410 -	if (it == inverse.end()) {
   1.411 -	  inverse.insert(std::make_pair(value, item));
   1.412 -	} else {
   1.413 -	  throw DataFormatError("Multiple ID occurence");
   1.414 -	}
   1.415 -      }
   1.416 -
   1.417 -      virtual Item read(std::istream& is) const {
   1.418 -	Value value;
   1.419 -	reader.read(is, value);	
   1.420 -	typename Inverse::const_iterator it = inverse.find(value);
   1.421 -	if (it != inverse.end()) {
   1.422 -	  return it->second;
   1.423 -	} else {
   1.424 -	  throw DataFormatError("Invalid ID error");
   1.425 -	}
   1.426 -      }      
   1.427 -    };
   1.428 -
   1.429 -    template <typename _Item, typename _Reader>
   1.430 -    class SkipReaderInverter : public InverterBase<_Item> {
   1.431 -    public:
   1.432 -      typedef _Item Item;
   1.433 -      typedef _Reader Reader;
   1.434 -      typedef typename Reader::Value Value;
   1.435 -      typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
   1.436 -
   1.437 -      Reader reader;
   1.438 -
   1.439 -      SkipReaderInverter(const Reader& _reader) 
   1.440 -	: reader(_reader) {}
   1.441 -
   1.442 -      virtual ~SkipReaderInverter() {}
   1.443 -
   1.444 -      virtual void read(std::istream& is, const Item& item) {
   1.445 -	Value value;
   1.446 -	reader.read(is, value);
   1.447 -	typename Inverse::iterator it = inverse.find(value);
   1.448 -	if (it == inverse.end()) {
   1.449 -	  inverse.insert(std::make_pair(value, item));
   1.450 -	} else {
   1.451 -	  throw DataFormatError("Multiple ID occurence error");
   1.452 -	}
   1.453 -      }
   1.454 -
   1.455 -      virtual Item read(std::istream& is) const {
   1.456 -	Value value;
   1.457 -	reader.read(is, value);	
   1.458 -	typename Inverse::const_iterator it = inverse.find(value);
   1.459 -	if (it != inverse.end()) {
   1.460 -	  return it->second;
   1.461 -	} else {
   1.462 -	  throw DataFormatError("Invalid ID error");
   1.463 -	}
   1.464 -      }
   1.465 -
   1.466 -    private:
   1.467 -      Inverse inverse;
   1.468 -    };
   1.469 -
   1.470 -    template <typename _Item>    
   1.471 -    class ReaderBase {
   1.472 -    public:
   1.473 -      typedef _Item Item;
   1.474 -
   1.475 -      virtual ~ReaderBase() {}
   1.476 -
   1.477 -      virtual void read(std::istream& is, const Item& item) = 0;
   1.478 -      virtual InverterBase<_Item>* getInverter() = 0;
   1.479 -    };
   1.480 -
   1.481 -    template <typename _Item, typename _Map, typename _Reader>
   1.482 -    class MapReader : public ReaderBase<_Item> {
   1.483 -    public:
   1.484 -      typedef _Map Map;
   1.485 -      typedef _Reader Reader;
   1.486 -      typedef typename Reader::Value Value;
   1.487 -      typedef _Item Item;
   1.488 -      
   1.489 -      typename SmartReference<Map>::Type map;
   1.490 -      Reader reader;
   1.491 -
   1.492 -      MapReader(typename SmartParameter<Map>::Type _map, 
   1.493 -		const Reader& _reader) 
   1.494 -	: map(_map), reader(_reader) {}
   1.495 -
   1.496 -      virtual ~MapReader() {}
   1.497 -
   1.498 -      virtual void read(std::istream& is, const Item& item) {
   1.499 -	Value value;
   1.500 -	reader.read(is, value);
   1.501 -	map.set(item, value);
   1.502 -      }
   1.503 -
   1.504 -      virtual InverterBase<_Item>* getInverter() {
   1.505 -	return new MapReaderInverter<Item, Map, Reader>(map, reader);
   1.506 -      }
   1.507 -    };
   1.508 -
   1.509 -
   1.510 -    template <typename _Item, typename _Reader>
   1.511 -    class SkipReader : public ReaderBase<_Item> {
   1.512 -    public:
   1.513 -      typedef _Reader Reader;
   1.514 -      typedef typename Reader::Value Value;
   1.515 -      typedef _Item Item;
   1.516 -
   1.517 -      Reader reader;
   1.518 -      SkipReader(const Reader& _reader) : reader(_reader) {}
   1.519 -
   1.520 -      virtual ~SkipReader() {}
   1.521 -
   1.522 -      virtual void read(std::istream& is, const Item&) {
   1.523 -	Value value;
   1.524 -	reader.read(is, value);
   1.525 -      }      
   1.526 -
   1.527 -      virtual InverterBase<Item>* getInverter() {
   1.528 -	return new SkipReaderInverter<Item, Reader>(reader);
   1.529 -      }
   1.530 -    };
   1.531 -
   1.532 -    template <typename _Item>
   1.533 -    class IdReaderBase {
   1.534 -    public:
   1.535 -      typedef _Item Item;
   1.536 -      virtual Item read(std::istream& is) const = 0;
   1.537 -    };
   1.538 -
   1.539 -    template <typename _Item, typename _BoxedIdReader>
   1.540 -    class IdReader : public IdReaderBase<_Item> {
   1.541 -    public:
   1.542 -      typedef _Item Item;
   1.543 -      typedef _BoxedIdReader BoxedIdReader;
   1.544 -      
   1.545 -      const BoxedIdReader& boxedIdReader;
   1.546 -
   1.547 -      IdReader(const BoxedIdReader& _boxedIdReader) 
   1.548 -	: boxedIdReader(_boxedIdReader) {}
   1.549 -
   1.550 -      virtual Item read(std::istream& is) const {
   1.551 -	return boxedIdReader.readId(is, Item());
   1.552 -      }
   1.553 -    };
   1.554 -
   1.555 -    class ValueReaderBase {
   1.556 -    public:
   1.557 -      virtual void read(std::istream&) {};
   1.558 -    };
   1.559 -
   1.560 -    template <typename _Value, typename _Reader>
   1.561 -    class ValueReader : public ValueReaderBase {
   1.562 -    public:
   1.563 -      typedef _Value Value;
   1.564 -      typedef _Reader Reader;
   1.565 -
   1.566 -      ValueReader(Value& _value, const Reader& _reader)
   1.567 - 	: value(_value), reader(_reader) {}
   1.568 -
   1.569 -      virtual void read(std::istream& is) {
   1.570 -	reader.read(is, value);
   1.571 -      }
   1.572 -    private:
   1.573 -      Value& value;
   1.574 -      Reader reader;
   1.575 -    };
   1.576 -    
   1.577 -  };
   1.578 -
   1.579 -  /// \ingroup io_group
   1.580 -  /// \brief SectionReader for reading a graph's nodeset.
   1.581 -  ///
   1.582 -  /// The lemon format can store multiple graph nodesets with several maps.
   1.583 -  /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the
   1.584 -  /// \c nodeset_id may be empty.
   1.585 -  ///
   1.586 -  /// The first line of the section contains the names of the maps separated
   1.587 -  /// with white spaces. Each next lines describes a node in the nodeset, and
   1.588 -  /// contains the mapped values for each map.
   1.589 -  ///
   1.590 -  /// If the nodeset contains an \c "id" named map then it will be regarded
   1.591 -  /// as id map. This map should contain only unique values and when the 
   1.592 -  /// \c readId() member will read a value from the given stream it will
   1.593 -  /// give back that node which is mapped to this value.
   1.594 -  ///
   1.595 -  /// \relates LemonReader
   1.596 -  template <typename _Graph, typename _Traits = DefaultReaderTraits>
   1.597 -  class NodeSetReader : public CommonSectionReaderBase {
   1.598 -    typedef CommonSectionReaderBase Parent;
   1.599 -  public:
   1.600 -
   1.601 -    typedef _Graph Graph;
   1.602 -    typedef _Traits Traits;
   1.603 -    typedef typename Graph::Node Node;
   1.604 -    typedef typename Traits::Skipper DefaultSkipper;
   1.605 -
   1.606 -    /// \brief Constructor.
   1.607 -    ///
   1.608 -    /// Constructor for NodeSetReader. It creates the NodeSetReader and
   1.609 -    /// attach it into the given LemonReader. The nodeset reader will
   1.610 -    /// add the readed nodes to the given Graph. The reader will read
   1.611 -    /// the section when the \c section_id and the \c _id are the same. 
   1.612 -    NodeSetReader(LemonReader& _reader, 
   1.613 -		  typename SmartParameter<Graph>::Type _graph, 
   1.614 -		  const std::string& _id = std::string(),
   1.615 -		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   1.616 -      : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {} 
   1.617 -
   1.618 -
   1.619 -    /// \brief Destructor.
   1.620 -    ///
   1.621 -    /// Destructor for NodeSetReader.
   1.622 -    virtual ~NodeSetReader() {
   1.623 -      for (typename MapReaders::iterator it = readers.begin(); 
   1.624 -	   it != readers.end(); ++it) {
   1.625 -	delete it->second;
   1.626 -      }
   1.627 -    }
   1.628 -
   1.629 -  private:
   1.630 -    NodeSetReader(const NodeSetReader&);
   1.631 -    void operator=(const NodeSetReader&);
   1.632 -  
   1.633 -  public:
   1.634 -
   1.635 -    /// \brief Add a new node map reader command for the reader.
   1.636 -    ///
   1.637 -    /// Add a new node map reader command for the reader.
   1.638 -    template <typename Map>
   1.639 -    NodeSetReader& readNodeMap(std::string name, Map& map) {
   1.640 -      return _readMap<
   1.641 -	typename Traits::template Reader<typename Map::Value>, Map,
   1.642 -	typename SmartParameter<Map>::Type>(name, map);
   1.643 -    }
   1.644 -
   1.645 -    template <typename Map>
   1.646 -    NodeSetReader& readNodeMap(std::string name, const Map& map) {
   1.647 -      return _readMap<
   1.648 -	typename Traits::template Reader<typename Map::Value>, Map,
   1.649 -	typename SmartParameter<Map>::Type>(name, map);
   1.650 -    }
   1.651 -
   1.652 -    /// \brief Add a new node map reader command for the reader.
   1.653 -    ///
   1.654 -    /// Add a new node map reader command for the reader.
   1.655 -    template <typename Reader, typename Map>
   1.656 -    NodeSetReader& readNodeMap(std::string name, Map& map, 
   1.657 -			       const Reader& reader = Reader()) {
   1.658 -      return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
   1.659 -	(name, map, reader);
   1.660 -    }
   1.661 -
   1.662 -    template <typename Reader, typename Map>
   1.663 -    NodeSetReader& readNodeMap(std::string name, const Map& map, 
   1.664 -			       const Reader& reader = Reader()) {
   1.665 -      return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
   1.666 -	(name, map, reader);
   1.667 -    }
   1.668 -
   1.669 -  private:
   1.670 -
   1.671 -    template <typename Reader, typename Map, typename MapParameter>
   1.672 -    NodeSetReader& _readMap(std::string name, MapParameter map, 
   1.673 -			    const Reader& reader = Reader()) {
   1.674 -      if (readers.find(name) != readers.end()) {
   1.675 -	ErrorMessage msg;
   1.676 -	msg << "Multiple read rule for node map: " << name;
   1.677 -	throw IOParameterError(msg.message());
   1.678 -      }
   1.679 -      readers.insert(
   1.680 -	make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
   1.681 -      return *this;
   1.682 -    }
   1.683 -
   1.684 -  public:
   1.685 -
   1.686 -    /// \brief Add a new node map skipper command for the reader.
   1.687 -    ///
   1.688 -    /// Add a new node map skipper command for the reader.
   1.689 -    template <typename Reader>
   1.690 -    NodeSetReader& skipNodeMap(std::string name, 
   1.691 -			   const Reader& reader = Reader()) {
   1.692 -      if (readers.find(name) != readers.end()) {
   1.693 -	ErrorMessage msg;
   1.694 -	msg << "Multiple read rule for node map: " << name;
   1.695 -	throw IOParameterError(msg.message());
   1.696 -      }
   1.697 -      readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
   1.698 -      return *this;
   1.699 -    }
   1.700 -
   1.701 -  protected:
   1.702 -
   1.703 -    /// \brief Gives back true when the SectionReader can process 
   1.704 -    /// the section with the given header line.
   1.705 -    ///
   1.706 -    /// It gives back true when the header line starts with \c \@nodeset,
   1.707 -    /// and the header line's id and the nodeset's id are the same.
   1.708 -    virtual bool header(const std::string& line) {
   1.709 -      std::istringstream ls(line);
   1.710 -      std::string command;
   1.711 -      std::string name;
   1.712 -      ls >> command >> name;
   1.713 -      return command == "@nodeset" && name == id;
   1.714 -    }
   1.715 -
   1.716 -    /// \brief Reader function of the section.
   1.717 -    ///
   1.718 -    /// It reads the content of the section.
   1.719 -    virtual void read(std::istream& is) {
   1.720 -      std::vector<ReaderBase<Node>* > index;
   1.721 -      std::string line;
   1.722 -
   1.723 -      getline(is, line);
   1.724 -      std::istringstream ls(line);	
   1.725 -      while (ls >> id) {
   1.726 -	typename MapReaders::iterator it = readers.find(id);
   1.727 -	if (it != readers.end()) {
   1.728 -	  index.push_back(it->second);
   1.729 -	} else {
   1.730 -	  index.push_back(&skipper);
   1.731 -	}
   1.732 -	if (id == "id" && inverter.get() == 0) {
   1.733 -	  inverter.reset(index.back()->getInverter());
   1.734 -	  index.back() = inverter.get();
   1.735 -	}
   1.736 -      }
   1.737 -      while (getline(is, line)) {	
   1.738 -	Node node = graph.addNode();
   1.739 -	std::istringstream ls(line);
   1.740 -	for (int i = 0; i < (int)index.size(); ++i) {
   1.741 -	  index[i]->read(ls, node);
   1.742 -	}
   1.743 -      }
   1.744 -    }
   1.745 -
   1.746 -  public:
   1.747 -
   1.748 -    /// \brief Returns true if the nodeset can give back the node by its id.
   1.749 -    ///
   1.750 -    /// Returns true if the nodeset can give back the node by its id.
   1.751 -    /// It is possible only if an "id" named map was read.
   1.752 -    bool isIdReader() const {
   1.753 -      return inverter.get() != 0;
   1.754 -    }
   1.755 -
   1.756 -    /// \brief Gives back the node by its id.
   1.757 -    ///
   1.758 -    /// It reads an id from the stream and gives back which node belongs to
   1.759 -    /// it. It is possible only if there was read an "id" named map.
   1.760 -    Node readId(std::istream& is, Node = Node()) const {
   1.761 -      return inverter->read(is);
   1.762 -    } 
   1.763 -
   1.764 -  private:
   1.765 -
   1.766 -    typedef std::map<std::string, ReaderBase<Node>*> MapReaders;
   1.767 -    MapReaders readers;
   1.768 -   
   1.769 -    typename SmartReference<Graph>::Type graph;   
   1.770 -    std::string id;
   1.771 -    SkipReader<Node, DefaultSkipper> skipper;
   1.772 -
   1.773 -    std::auto_ptr<InverterBase<Node> > inverter;
   1.774 -  };
   1.775 -
   1.776 -  /// \ingroup io_group
   1.777 -  /// \brief SectionReader for reading a graph's edgeset.
   1.778 -  ///
   1.779 -  /// The lemon format can store multiple graph edgesets with several maps.
   1.780 -  /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
   1.781 -  /// \c edgeset_id may be empty.
   1.782 -  ///
   1.783 -  /// The first line of the section contains the names of the maps separated
   1.784 -  /// with white spaces. Each next lines describes an edge in the edgeset. The
   1.785 -  /// line contains the source and the target nodes' id and the mapped 
   1.786 -  /// values for each map.
   1.787 -  ///
   1.788 -  /// If the edgeset contains an \c "id" named map then it will be regarded
   1.789 -  /// as id map. This map should contain only unique values and when the 
   1.790 -  /// \c readId() member will read a value from the given stream it will
   1.791 -  /// give back that edge which is mapped to this value.
   1.792 -  ///
   1.793 -  /// The edgeset reader needs a node id reader to identify which nodes
   1.794 -  /// have to be connected. If a NodeSetReader reads an "id" named map,
   1.795 -  /// it will be able to resolve the nodes by ids.
   1.796 -  ///
   1.797 -  /// \relates LemonReader
   1.798 -  template <typename _Graph, typename _Traits = DefaultReaderTraits>
   1.799 -  class EdgeSetReader : public CommonSectionReaderBase {
   1.800 -    typedef CommonSectionReaderBase Parent;
   1.801 -  public:
   1.802 -
   1.803 -    typedef _Graph Graph;
   1.804 -    typedef _Traits Traits;
   1.805 -    typedef typename Graph::Node Node;
   1.806 -    typedef typename Graph::Edge Edge;
   1.807 -    typedef typename Traits::Skipper DefaultSkipper;
   1.808 -
   1.809 -    /// \brief Constructor.
   1.810 -    ///
   1.811 -    /// Constructor for EdgeSetReader. It creates the EdgeSetReader and
   1.812 -    /// attach it into the given LemonReader. The edgeset reader will
   1.813 -    /// add the readed edges to the given Graph. It will use the given
   1.814 -    /// node id reader to read the source and target nodes of the edges.
   1.815 -    /// The reader will read the section only if the \c _id and the 
   1.816 -    /// \c edgset_id are the same. 
   1.817 -    template <typename NodeIdReader>
   1.818 -    EdgeSetReader(LemonReader& _reader, 
   1.819 -		  typename SmartParameter<Graph>::Type _graph, 
   1.820 -		  const NodeIdReader& _nodeIdReader, 
   1.821 -		  const std::string& _id = std::string(),
   1.822 -		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   1.823 -      : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
   1.824 -	nodeIdReader(new IdReader<Node, NodeIdReader>(_nodeIdReader)) {} 
   1.825 -
   1.826 -    /// \brief Destructor.
   1.827 -    ///
   1.828 -    /// Destructor for EdgeSetReader.
   1.829 -    virtual ~EdgeSetReader() {
   1.830 -      for (typename MapReaders::iterator it = readers.begin(); 
   1.831 -	   it != readers.end(); ++it) {
   1.832 -	delete it->second;
   1.833 -      }
   1.834 -    }
   1.835 -
   1.836 -  private:
   1.837 -    EdgeSetReader(const EdgeSetReader&);
   1.838 -    void operator=(const EdgeSetReader&);
   1.839 -
   1.840 -  public:
   1.841 -
   1.842 -    /// \brief Add a new edge map reader command for the reader.
   1.843 -    ///
   1.844 -    /// Add a new edge map reader command for the reader.
   1.845 -    template <typename Map>
   1.846 -    EdgeSetReader& readEdgeMap(std::string name, Map& map) {
   1.847 -      return _readMap<
   1.848 -	typename Traits::template Reader<typename Map::Value>, Map,
   1.849 -	typename SmartParameter<Map>::Type>(name, map);
   1.850 -    }
   1.851 -
   1.852 -    template <typename Map>
   1.853 -    EdgeSetReader& readEdgeMap(std::string name, const Map& map) {
   1.854 -      return _readMap<
   1.855 -	typename Traits::template Reader<typename Map::Value>, Map,
   1.856 -	typename SmartParameter<Map>::Type>(name, map);
   1.857 -    }
   1.858 -
   1.859 -    /// \brief Add a new edge map reader command for the reader.
   1.860 -    ///
   1.861 -    /// Add a new edge map reader command for the reader.
   1.862 -    template <typename Reader, typename Map>
   1.863 -    EdgeSetReader& readEdgeMap(std::string name, Map& map, 
   1.864 -			   const Reader& reader = Reader()) {
   1.865 -      return _readMap<Reader, Map,
   1.866 -	typename SmartParameter<Map>::Type>(name, map, reader);
   1.867 -    }
   1.868 -
   1.869 -    template <typename Reader, typename Map>
   1.870 -    EdgeSetReader& readEdgeMap(std::string name, const Map& map, 
   1.871 -			       const Reader& reader = Reader()) {
   1.872 -      return _readMap<Reader, Map,
   1.873 -	typename SmartParameter<Map>::Type>(name, map, reader);
   1.874 -    }
   1.875 -
   1.876 -  private:
   1.877 -
   1.878 -    template <typename Reader, typename Map, typename MapParameter>
   1.879 -    EdgeSetReader& _readMap(std::string name, MapParameter map, 
   1.880 -			    const Reader& reader = Reader()) {
   1.881 -      if (readers.find(name) != readers.end()) {
   1.882 -	ErrorMessage msg;
   1.883 -	msg << "Multiple read rule for edge map: " << name;
   1.884 -	throw IOParameterError(msg.message());
   1.885 -      }
   1.886 -      readers.insert(
   1.887 -	make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   1.888 -      return *this;
   1.889 -    }
   1.890 -
   1.891 -  public:
   1.892 -
   1.893 -    /// \brief Add a new edge map skipper command for the reader.
   1.894 -    ///
   1.895 -    /// Add a new edge map skipper command for the reader.
   1.896 -    template <typename Reader>
   1.897 -    EdgeSetReader& skipEdgeMap(std::string name, 
   1.898 -			       const Reader& reader = Reader()) {
   1.899 -      if (readers.find(name) != readers.end()) {
   1.900 -	ErrorMessage msg;
   1.901 -	msg << "Multiple read rule for edge map: " << name;
   1.902 -	throw IOParameterError(msg.message());
   1.903 -      }
   1.904 -      readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
   1.905 -      return *this;
   1.906 -    }
   1.907 -
   1.908 -  protected:
   1.909 -
   1.910 -    /// \brief Gives back true when the SectionReader can process 
   1.911 -    /// the section with the given header line.
   1.912 -    ///
   1.913 -    /// It gives back true when the header line starts with \c \@edgeset,
   1.914 -    /// and the header line's id and the edgeset's id are the same.
   1.915 -    virtual bool header(const std::string& line) {
   1.916 -      std::istringstream ls(line);
   1.917 -      std::string command;
   1.918 -      std::string name;
   1.919 -      ls >> command >> name;
   1.920 -      return command == "@edgeset" && name == id;
   1.921 -    }
   1.922 -
   1.923 -    /// \brief Reader function of the section.
   1.924 -    ///
   1.925 -    /// It reads the content of the section.
   1.926 -    virtual void read(std::istream& is) {
   1.927 -      std::vector<ReaderBase<Edge>* > index;
   1.928 -      std::string line;
   1.929 -
   1.930 -      getline(is, line);
   1.931 -      std::istringstream ls(line);	
   1.932 -      while (ls >> id) {
   1.933 -	typename MapReaders::iterator it = readers.find(id);
   1.934 -	if (it != readers.end()) {
   1.935 -	  index.push_back(it->second);
   1.936 -	} else {
   1.937 -	  index.push_back(&skipper);
   1.938 -	}
   1.939 -	if (id == "id" && inverter.get() == 0) {
   1.940 -	  inverter.reset(index.back()->getInverter());
   1.941 -	  index.back() = inverter.get();
   1.942 -	}
   1.943 -      }
   1.944 -      while (getline(is, line)) {	
   1.945 -	std::istringstream ls(line);
   1.946 -	Node from = nodeIdReader->read(ls);
   1.947 -	Node to = nodeIdReader->read(ls);
   1.948 -	Edge edge = graph.addEdge(from, to);
   1.949 -	for (int i = 0; i < (int)index.size(); ++i) {
   1.950 -	  index[i]->read(ls, edge);
   1.951 -	}
   1.952 -      }
   1.953 -    }
   1.954 -
   1.955 -  public:
   1.956 -
   1.957 -    /// \brief Returns true if the edgeset can give back the edge by its id.
   1.958 -    ///
   1.959 -    /// Returns true if the edgeset can give back the edge by its id.
   1.960 -    /// It is possible only if an "id" named map was read.
   1.961 -    bool isIdReader() const {
   1.962 -      return inverter.get() != 0;
   1.963 -    }
   1.964 -
   1.965 -    /// \brief Gives back the edge by its id.
   1.966 -    ///
   1.967 -    /// It reads an id from the stream and gives back which edge belongs to
   1.968 -    /// it. It is possible only if there was read an "id" named map.
   1.969 -    Edge readId(std::istream& is, Edge = Edge()) const {
   1.970 -      return inverter->read(is);
   1.971 -    } 
   1.972 -
   1.973 -  private:
   1.974 -
   1.975 -    typedef std::map<std::string, ReaderBase<Edge>*> MapReaders;
   1.976 -    MapReaders readers;
   1.977 -   
   1.978 -    typename SmartReference<Graph>::Type graph;   
   1.979 -    std::string id;
   1.980 -    SkipReader<Edge, DefaultSkipper> skipper;
   1.981 -
   1.982 -    std::auto_ptr<InverterBase<Edge> > inverter;
   1.983 -    std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
   1.984 -  };
   1.985 -
   1.986 -  /// \ingroup io_group
   1.987 -  /// \brief SectionReader for reading a undirected graph's edgeset.
   1.988 -  ///
   1.989 -  /// The lemon format can store multiple undirected edgesets with several 
   1.990 -  /// maps. The undirected edgeset section's header line is \c \@undiredgeset 
   1.991 -  /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
   1.992 -  ///
   1.993 -  /// The first line of the section contains the names of the maps separated
   1.994 -  /// with white spaces. Each next lines describes an edge in the edgeset. The
   1.995 -  /// line contains the connected nodes' id and the mapped values for each map.
   1.996 -  ///
   1.997 -  /// The section can handle the directed as a syntactical sugar. Two
   1.998 -  /// undirected edge map describes one directed edge map. This two maps
   1.999 -  /// are the forward map and the backward map and the names of this map
  1.1000 -  /// is near the same just with a prefix \c '+' or \c '-' character 
  1.1001 -  /// difference.
  1.1002 -  ///
  1.1003 -  /// If the edgeset contains an \c "id" named map then it will be regarded
  1.1004 -  /// as id map. This map should contain only unique values and when the 
  1.1005 -  /// \c readId() member will read a value from the given stream it will
  1.1006 -  /// give back that undiricted edge which is mapped to this value.
  1.1007 -  ///
  1.1008 -  /// The undirected edgeset reader needs a node id reader to identify which 
  1.1009 -  /// nodes have to be connected. If a NodeSetReader reads an "id" named map,
  1.1010 -  /// it will be able to resolve the nodes by ids.
  1.1011 -  ///
  1.1012 -  /// \relates LemonReader
  1.1013 -  template <typename _Graph, typename _Traits = DefaultReaderTraits>
  1.1014 -  class UndirEdgeSetReader : public CommonSectionReaderBase {
  1.1015 -    typedef CommonSectionReaderBase Parent;
  1.1016 -  public:
  1.1017 -
  1.1018 -    typedef _Graph Graph;
  1.1019 -    typedef _Traits Traits;
  1.1020 -    typedef typename Graph::Node Node;
  1.1021 -    typedef typename Graph::Edge Edge;
  1.1022 -    typedef typename Graph::UndirEdge UndirEdge;
  1.1023 -    typedef typename Traits::Skipper DefaultSkipper;
  1.1024 -
  1.1025 -    /// \brief Constructor.
  1.1026 -    ///
  1.1027 -    /// Constructor for UndirEdgeSetReader. It creates the UndirEdgeSetReader 
  1.1028 -    /// and attach it into the given LemonReader. The undirected edgeset 
  1.1029 -    /// reader will add the readed undirected edges to the given Graph. It 
  1.1030 -    /// will use the given node id reader to read the source and target 
  1.1031 -    /// nodes of the edges. The reader will read the section only if the 
  1.1032 -    /// \c _id and the \c undiredgset_id are the same. 
  1.1033 -    template <typename NodeIdReader>
  1.1034 -    UndirEdgeSetReader(LemonReader& _reader, 
  1.1035 -		       typename SmartParameter<Graph>::Type _graph, 
  1.1036 -		       const NodeIdReader& _nodeIdReader, 
  1.1037 -		       const std::string& _id = std::string(),
  1.1038 -		       const DefaultSkipper& _skipper = DefaultSkipper()) 
  1.1039 -      : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
  1.1040 -	nodeIdReader(new IdReader<Node, NodeIdReader>(_nodeIdReader)) {} 
  1.1041 -
  1.1042 -    /// \brief Destructor.
  1.1043 -    ///
  1.1044 -    /// Destructor for UndirEdgeSetReader.
  1.1045 -    virtual ~UndirEdgeSetReader() {
  1.1046 -      for (typename MapReaders::iterator it = readers.begin(); 
  1.1047 -	   it != readers.end(); ++it) {
  1.1048 -	delete it->second;
  1.1049 -      }
  1.1050 -    }
  1.1051 -
  1.1052 -  private:
  1.1053 -    UndirEdgeSetReader(const UndirEdgeSetReader&);
  1.1054 -    void operator=(const UndirEdgeSetReader&);
  1.1055 -
  1.1056 -  public:
  1.1057 -
  1.1058 -    /// \brief Add a new undirected edge map reader command for the reader.
  1.1059 -    ///
  1.1060 -    /// Add a new edge undirected map reader command for the reader.
  1.1061 -    template <typename Map>
  1.1062 -    UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map) {
  1.1063 -      return _readMap<
  1.1064 -	typename Traits::template Reader<typename Map::Value>, Map, 
  1.1065 -	typename SmartParameter<Map>::Type>(name, map);
  1.1066 -    }
  1.1067 -
  1.1068 -    template <typename Map>
  1.1069 -    UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map) {
  1.1070 -      return _readMap<
  1.1071 -	typename Traits::template Reader<typename Map::Value>, Map, 
  1.1072 -	typename SmartParameter<Map>::Type>(name, map);
  1.1073 -    }
  1.1074 -
  1.1075 -    /// \brief Add a new undirected edge map reader command for the reader.
  1.1076 -    ///
  1.1077 -    /// Add a new edge undirected map reader command for the reader.
  1.1078 -    template <typename Reader, typename Map>
  1.1079 -    UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map, 
  1.1080 -					 const Reader& reader = Reader()) {
  1.1081 -      return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
  1.1082 -	(name, map, reader);
  1.1083 -    }
  1.1084 -
  1.1085 -    template <typename Reader, typename Map>
  1.1086 -    UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map, 
  1.1087 -					 const Reader& reader = Reader()) {
  1.1088 -      return _readMap<Reader, Map, typename SmartParameter<Map>::Type >
  1.1089 -	(name, map, reader);
  1.1090 -    }
  1.1091 -
  1.1092 -  private:
  1.1093 -
  1.1094 -    template <typename Reader, typename Map, typename MapParameter>
  1.1095 -    UndirEdgeSetReader& _readMap(std::string name, MapParameter map,
  1.1096 -				 const Reader& reader = Reader()) {
  1.1097 -      if (readers.find(name) != readers.end()) {
  1.1098 -	ErrorMessage msg;
  1.1099 -	msg << "Multiple read rule for edge map: " << name;
  1.1100 -	throw IOParameterError(msg.message());
  1.1101 -      }
  1.1102 -      readers.insert(
  1.1103 -	make_pair(name, new MapReader<UndirEdge, Map, Reader>(map, reader)));
  1.1104 -      return *this;
  1.1105 -    }
  1.1106 -
  1.1107 -  public:
  1.1108 -
  1.1109 -    /// \brief Add a new undirected edge map skipper command for the reader.
  1.1110 -    ///
  1.1111 -    /// Add a new undirected edge map skipper command for the reader.
  1.1112 -    template <typename Reader>
  1.1113 -    UndirEdgeSetReader& skipUndirEdgeMap(std::string name, 
  1.1114 -					 const Reader& reader = Reader()) {
  1.1115 -      if (readers.find(name) != readers.end()) {
  1.1116 -	ErrorMessage msg;
  1.1117 -	msg << "Multiple read rule for node map: " << name;
  1.1118 -	throw IOParameterError(msg.message());
  1.1119 -      }
  1.1120 -      readers.insert(make_pair(name, 
  1.1121 -			       new SkipReader<UndirEdge, Reader>(reader)));
  1.1122 -      return *this;
  1.1123 -    }
  1.1124 -
  1.1125 -    /// \brief Add a new directed edge map reader command for the reader.
  1.1126 -    ///
  1.1127 -    /// Add a new directed edge map reader command for the reader.
  1.1128 -    template <typename Map>
  1.1129 -    UndirEdgeSetReader& readEdgeMap(std::string name, Map& map) {
  1.1130 -      return _readDirMap<
  1.1131 -	typename Traits::template Reader<typename Map::Value>, Map,
  1.1132 -	typename SmartParameter<Map>::Type>(name, map);
  1.1133 -    }
  1.1134 -
  1.1135 -    template <typename Map>
  1.1136 -    UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map) {
  1.1137 -      return _readDirMap<
  1.1138 -	typename Traits::template Reader<typename Map::Value>, Map,
  1.1139 -	typename SmartParameter<Map>::Type>(name, map);
  1.1140 -    }
  1.1141 -
  1.1142 -    /// \brief Add a new directed edge map reader command for the reader.
  1.1143 -    ///
  1.1144 -    /// Add a new directed edge map reader command for the reader.
  1.1145 -    template <typename Reader, typename Map>
  1.1146 -    UndirEdgeSetReader& readEdgeMap(std::string name, Map& map, 
  1.1147 -				    const Reader& reader = Reader()) {
  1.1148 -      return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
  1.1149 -	(name, map, reader);
  1.1150 -    }
  1.1151 -
  1.1152 -    template <typename Reader, typename Map>
  1.1153 -    UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map, 
  1.1154 -				    const Reader& reader = Reader()) {
  1.1155 -      return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
  1.1156 -	(name, map, reader);
  1.1157 -    }
  1.1158 -
  1.1159 -  private:
  1.1160 -
  1.1161 -    template <typename Reader, typename Map, typename MapParameter>
  1.1162 -    UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map,
  1.1163 -				    const Reader& reader = Reader()) {
  1.1164 -      readMap("+" + name, 
  1.1165 -	      _reader_bits::writeComposeMap(map, forwardMap(graph)), reader);
  1.1166 -      readMap("-" + name, 
  1.1167 -	      _reader_bits::writeComposeMap(map, backwardMap(graph)), reader);
  1.1168 -      return *this;      
  1.1169 -    }
  1.1170 -
  1.1171 -  public:
  1.1172 -
  1.1173 -    /// \brief Add a new directed edge map skipper command for the reader.
  1.1174 -    ///
  1.1175 -    /// Add a new directed edge map skipper command for the reader.
  1.1176 -    template <typename Reader>
  1.1177 -    UndirEdgeSetReader& skipEdgeMap(std::string name, 
  1.1178 -				    const Reader& reader = Reader()) {
  1.1179 -      skipMap("+" + name, reader);
  1.1180 -      skipMap("-" + name, reader);
  1.1181 -      return *this;
  1.1182 -    }
  1.1183 -
  1.1184 -  protected:
  1.1185 -
  1.1186 -    /// \brief Gives back true when the SectionReader can process 
  1.1187 -    /// the section with the given header line.
  1.1188 -    ///
  1.1189 -    /// It gives back true when the header line starts with \c \@undiredgeset,
  1.1190 -    /// and the header line's id and the edgeset's id are the same.
  1.1191 -    virtual bool header(const std::string& line) {
  1.1192 -      std::istringstream ls(line);
  1.1193 -      std::string command;
  1.1194 -      std::string name;
  1.1195 -      ls >> command >> name;
  1.1196 -      return command == "@undiredgeset" && name == id;
  1.1197 -    }
  1.1198 -
  1.1199 -    /// \brief Reader function of the section.
  1.1200 -    ///
  1.1201 -    /// It reads the content of the section.
  1.1202 -    virtual void read(std::istream& is) {
  1.1203 -      std::vector<ReaderBase<UndirEdge>* > index;
  1.1204 -      std::string line;
  1.1205 -
  1.1206 -      getline(is, line);
  1.1207 -      std::istringstream ls(line);	
  1.1208 -      while (ls >> id) {
  1.1209 -	typename MapReaders::iterator it = readers.find(id);
  1.1210 -	if (it != readers.end()) {
  1.1211 -	  index.push_back(it->second);
  1.1212 -	} else {
  1.1213 -	  index.push_back(&skipper);
  1.1214 -	}
  1.1215 -	if (id == "id" && inverter.get() == 0) {
  1.1216 -	  inverter.reset(index.back()->getInverter());
  1.1217 -	  index.back() = inverter.get();
  1.1218 -	}
  1.1219 -      }
  1.1220 -      while (getline(is, line)) {	
  1.1221 -	std::istringstream ls(line);
  1.1222 -	Node from = nodeIdReader->read(ls);
  1.1223 -	Node to = nodeIdReader->read(ls);
  1.1224 -	UndirEdge edge = graph.addEdge(from, to);
  1.1225 -	for (int i = 0; i < (int)index.size(); ++i) {
  1.1226 -	  index[i]->read(ls, edge);
  1.1227 -	}
  1.1228 -      }
  1.1229 -    }
  1.1230 -
  1.1231 -  public:
  1.1232 -
  1.1233 -    /// \brief Returns true if the edgeset can give back the edge by its id.
  1.1234 -    ///
  1.1235 -    /// Returns true if the edgeset can give back the undirected edge by its 
  1.1236 -    /// id. It is possible only if an "id" named map was read.
  1.1237 -    bool isIdReader() const {
  1.1238 -      return inverter.get() != 0;
  1.1239 -    }
  1.1240 -
  1.1241 -    /// \brief Gives back the undirected edge by its id.
  1.1242 -    ///
  1.1243 -    /// It reads an id from the stream and gives back which undirected edge 
  1.1244 -    /// belongs to it. It is possible only if there was read an "id" named map.
  1.1245 -    UndirEdge readId(std::istream& is, UndirEdge = UndirEdge()) const {
  1.1246 -      return inverter->read(is);
  1.1247 -    } 
  1.1248 -
  1.1249 -    /// \brief Gives back the directed edge by its id.
  1.1250 -    ///
  1.1251 -    /// It reads an id from the stream and gives back which directed edge 
  1.1252 -    /// belongs to it. The directed edge id is the \c '+' or \c '-' character
  1.1253 -    /// and the undirected edge id. It is possible only if there was read 
  1.1254 -    /// an "id" named map.
  1.1255 -    Edge readId(std::istream& is, Edge = Edge()) const {
  1.1256 -      char c;
  1.1257 -      is >> c;
  1.1258 -      UndirEdge undirEdge = inverter->read(is);
  1.1259 -      if (c == '+') {
  1.1260 -	return graph.edgeWithSource(undirEdge, graph.source(undirEdge));
  1.1261 -      } else if (c == '-') {
  1.1262 -	return graph.edgeWithSource(undirEdge, graph.target(undirEdge));
  1.1263 -      } else {
  1.1264 -	throw DataFormatError("Wrong id format for edge "
  1.1265 -			      "in undirected edgeset");
  1.1266 -      }
  1.1267 -    } 
  1.1268 -
  1.1269 -  private:
  1.1270 -
  1.1271 -    typedef std::map<std::string, ReaderBase<UndirEdge>*> MapReaders;
  1.1272 -    MapReaders readers;
  1.1273 -   
  1.1274 -    typename SmartReference<Graph>::Type graph;   
  1.1275 -    std::string id;
  1.1276 -    SkipReader<UndirEdge, DefaultSkipper> skipper;
  1.1277 -
  1.1278 -    std::auto_ptr<InverterBase<UndirEdge> > inverter;
  1.1279 -    std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
  1.1280 -  };
  1.1281 -
  1.1282 -  /// \ingroup io_group
  1.1283 -  /// \brief SectionReader for reading labeled nodes.
  1.1284 -  ///
  1.1285 -  /// The nodes section's header line is \c \@nodes \c nodes_id, but the
  1.1286 -  /// \c nodes_id may be empty.
  1.1287 -  ///
  1.1288 -  /// Each line in the section contains the name of the node 
  1.1289 -  /// and then the node id. 
  1.1290 -  ///
  1.1291 -  /// \relates LemonReader
  1.1292 -  template <typename _Graph>
  1.1293 -  class NodeReader : public CommonSectionReaderBase {
  1.1294 -    typedef CommonSectionReaderBase Parent;
  1.1295 -    typedef _Graph Graph;
  1.1296 -    typedef typename Graph::Node Node;
  1.1297 -  public:
  1.1298 -    
  1.1299 -    /// \brief Constructor.
  1.1300 -    ///
  1.1301 -    /// Constructor for NodeReader. It creates the NodeReader and
  1.1302 -    /// attach it into the given LemonReader. It will use the given
  1.1303 -    /// node id reader to give back the nodes. The reader will read the 
  1.1304 -    /// section only if the \c _id and the \c nodes_id are the same. 
  1.1305 -    template <typename _IdReader>
  1.1306 -    NodeReader(LemonReader& _reader, const _IdReader& _idReader, 
  1.1307 -	       const std::string& _id = std::string()) 
  1.1308 -      : Parent(_reader), id(_id), 
  1.1309 -	idReader(new IdReader<typename Graph::Node, _IdReader>(_idReader)) {} 
  1.1310 -
  1.1311 -    /// \brief Destructor.
  1.1312 -    ///
  1.1313 -    /// Destructor for NodeReader.
  1.1314 -    virtual ~NodeReader() {}
  1.1315 -
  1.1316 -  private:
  1.1317 -    NodeReader(const NodeReader&);
  1.1318 -    void operator=(const NodeReader&);
  1.1319 -
  1.1320 -  public:
  1.1321 -
  1.1322 -    /// \brief Add a node reader command for the NodeReader.
  1.1323 -    ///
  1.1324 -    /// Add a node reader command for the NodeReader.
  1.1325 -    void readNode(const std::string& name, Node& item) {
  1.1326 -      if (readers.find(name) != readers.end()) {
  1.1327 -	ErrorMessage msg;
  1.1328 -	msg << "Multiple read rule for node: " << name;
  1.1329 -	throw IOParameterError(msg.message());
  1.1330 -      }
  1.1331 -      readers.insert(make_pair(name, &item));
  1.1332 -    }
  1.1333 -
  1.1334 -  protected:
  1.1335 -
  1.1336 -    /// \brief Gives back true when the SectionReader can process 
  1.1337 -    /// the section with the given header line.
  1.1338 -    ///
  1.1339 -    /// It gives back true when the header line start with \c \@nodes,
  1.1340 -    /// and the header line's id and the reader's id are the same.
  1.1341 -    virtual bool header(const std::string& line) {
  1.1342 -      std::istringstream ls(line);
  1.1343 -      std::string command;
  1.1344 -      std::string name;
  1.1345 -      ls >> command >> name;
  1.1346 -      return command == "@nodes" && name == id;
  1.1347 -    }
  1.1348 -
  1.1349 -    /// \brief Reader function of the section.
  1.1350 -    ///
  1.1351 -    /// It reads the content of the section.
  1.1352 -    virtual void read(std::istream& is) {
  1.1353 -      std::string line;
  1.1354 -      while (getline(is, line)) {
  1.1355 -	std::istringstream ls(line);
  1.1356 -	std::string id;
  1.1357 -	ls >> id;
  1.1358 -	typename NodeReaders::iterator it = readers.find(id);
  1.1359 -	if (it != readers.end()) {
  1.1360 -	  *(it->second) = idReader->read(ls); 
  1.1361 -	}	
  1.1362 -      }
  1.1363 -    }
  1.1364 -    
  1.1365 -  private:
  1.1366 -
  1.1367 -    std::string id;
  1.1368 -
  1.1369 -    typedef std::map<std::string, Node*> NodeReaders;
  1.1370 -    NodeReaders readers;
  1.1371 -    std::auto_ptr<IdReaderBase<Node> > idReader;
  1.1372 -  };
  1.1373 -
  1.1374 -  /// \ingroup io_group
  1.1375 -  /// \brief SectionReader for reading labeled edges.
  1.1376 -  ///
  1.1377 -  /// The edges section's header line is \c \@edges \c edges_id, but the
  1.1378 -  /// \c edges_id may be empty.
  1.1379 -  ///
  1.1380 -  /// Each line in the section contains the name of the edge 
  1.1381 -  /// and then the edge id. 
  1.1382 -  ///
  1.1383 -  /// \relates LemonReader
  1.1384 -  template <typename _Graph>
  1.1385 -  class EdgeReader : public CommonSectionReaderBase {
  1.1386 -    typedef CommonSectionReaderBase Parent;
  1.1387 -    typedef _Graph Graph;
  1.1388 -    typedef typename Graph::Edge Edge;
  1.1389 -  public:
  1.1390 -    
  1.1391 -    /// \brief Constructor.
  1.1392 -    ///
  1.1393 -    /// Constructor for EdgeReader. It creates the EdgeReader and
  1.1394 -    /// attach it into the given LemonReader. It will use the given
  1.1395 -    /// edge id reader to give back the edges. The reader will read the 
  1.1396 -    /// section only if the \c _id and the \c edges_id are the same. 
  1.1397 -    template <typename _IdReader>
  1.1398 -    EdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
  1.1399 -	       const std::string& _id = std::string()) 
  1.1400 -      : Parent(_reader), id(_id), 
  1.1401 -	idReader(new IdReader<typename Graph::Edge, _IdReader>(_idReader)) {} 
  1.1402 -
  1.1403 -    /// \brief Destructor.
  1.1404 -    ///
  1.1405 -    /// Destructor for EdgeReader.
  1.1406 -    virtual ~EdgeReader() {}
  1.1407 -  private:
  1.1408 -    EdgeReader(const EdgeReader&);
  1.1409 -    void operator=(const EdgeReader&);
  1.1410 -
  1.1411 -  public:
  1.1412 -
  1.1413 -    /// \brief Add an edge reader command for the EdgeReader.
  1.1414 -    ///
  1.1415 -    /// Add an edge reader command for the EdgeReader.
  1.1416 -    void readEdge(const std::string& name, Edge& item) {
  1.1417 -      if (readers.find(name) != readers.end()) {
  1.1418 -	ErrorMessage msg;
  1.1419 -	msg << "Multiple read rule for edge: " << name;
  1.1420 -	throw IOParameterError(msg.message());
  1.1421 -      }
  1.1422 -      readers.insert(make_pair(name, &item));
  1.1423 -    }
  1.1424 -
  1.1425 -  protected:
  1.1426 -
  1.1427 -    /// \brief Gives back true when the SectionReader can process 
  1.1428 -    /// the section with the given header line.
  1.1429 -    ///
  1.1430 -    /// It gives back true when the header line start with \c \@edges,
  1.1431 -    /// and the header line's id and the reader's id are the same.
  1.1432 -    virtual bool header(const std::string& line) {
  1.1433 -      std::istringstream ls(line);
  1.1434 -      std::string command;
  1.1435 -      std::string name;
  1.1436 -      ls >> command >> name;
  1.1437 -      return command == "@edges" && name == id;
  1.1438 -    }
  1.1439 -
  1.1440 -    /// \brief Reader function of the section.
  1.1441 -    ///
  1.1442 -    /// It reads the content of the section.
  1.1443 -    virtual void read(std::istream& is) {
  1.1444 -      std::string line;
  1.1445 -      while (getline(is, line)) {
  1.1446 -	std::istringstream ls(line);
  1.1447 -	std::string id;
  1.1448 -	ls >> id;
  1.1449 -	typename EdgeReaders::iterator it = readers.find(id);
  1.1450 -	if (it != readers.end()) {
  1.1451 -	  *(it->second) = idReader->read(ls); 
  1.1452 -	}	
  1.1453 -      }
  1.1454 -    }
  1.1455 -    
  1.1456 -  private:
  1.1457 -
  1.1458 -    std::string id;
  1.1459 -
  1.1460 -    typedef std::map<std::string, Edge*> EdgeReaders;
  1.1461 -    EdgeReaders readers;
  1.1462 -    std::auto_ptr<IdReaderBase<Edge> > idReader;
  1.1463 -  };
  1.1464 -
  1.1465 -  /// \ingroup io_group
  1.1466 -  /// \brief SectionReader for reading labeled undirected edges.
  1.1467 -  ///
  1.1468 -  /// The undirected edges section's header line is \c \@undiredges 
  1.1469 -  /// \c undiredges_id, but the \c undiredges_id may be empty.
  1.1470 -  ///
  1.1471 -  /// Each line in the section contains the name of the undirected edge 
  1.1472 -  /// and then the undirected edge id. 
  1.1473 -  ///
  1.1474 -  /// \relates LemonReader
  1.1475 -  template <typename _Graph>
  1.1476 -  class UndirEdgeReader : public CommonSectionReaderBase {
  1.1477 -    typedef CommonSectionReaderBase Parent;
  1.1478 -    typedef _Graph Graph;
  1.1479 -    typedef typename Graph::Edge Edge;
  1.1480 -    typedef typename Graph::UndirEdge UndirEdge;
  1.1481 -  public:
  1.1482 -    
  1.1483 -    /// \brief Constructor.
  1.1484 -    ///
  1.1485 -    /// Constructor for UndirEdgeReader. It creates the UndirEdgeReader and
  1.1486 -    /// attach it into the given LemonReader. It will use the given
  1.1487 -    /// undirected edge id reader to give back the edges. The reader will 
  1.1488 -    /// read the section only if the \c _id and the \c undiredges_id are 
  1.1489 -    /// the same. 
  1.1490 -    template <typename _IdReader>
  1.1491 -    UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
  1.1492 -	       const std::string& _id = std::string()) 
  1.1493 -      : Parent(_reader), id(_id), 
  1.1494 -	undirEdgeIdReader(new IdReader<UndirEdge, _IdReader>(_idReader)),
  1.1495 -	edgeIdReader(new IdReader<Edge, _IdReader>(_idReader))
  1.1496 -    {} 
  1.1497 -
  1.1498 -    /// \brief Destructor.
  1.1499 -    ///
  1.1500 -    /// Destructor for UndirEdgeReader.
  1.1501 -    virtual ~UndirEdgeReader() {}
  1.1502 -  private:
  1.1503 -    UndirEdgeReader(const UndirEdgeReader&);
  1.1504 -    void operator=(const UndirEdgeReader&);
  1.1505 -
  1.1506 -  public:
  1.1507 -
  1.1508 -    /// \brief Add an undirected edge reader command for the UndirEdgeReader.
  1.1509 -    ///
  1.1510 -    /// Add an undirected edge reader command for the UndirEdgeReader.
  1.1511 -    void readUndirEdge(const std::string& name, UndirEdge& item) {
  1.1512 -      if (undirEdgeReaders.find(name) != undirEdgeReaders.end()) {
  1.1513 -	ErrorMessage msg;
  1.1514 -	msg << "Multiple read rule for undirected edge: " << name;
  1.1515 -	throw IOParameterError(msg.message());
  1.1516 -      }
  1.1517 -      undirEdgeReaders.insert(make_pair(name, &item));
  1.1518 -    }
  1.1519 -
  1.1520 -    /// \brief Add an edge reader command for the UndirEdgeReader.
  1.1521 -    ///
  1.1522 -    /// Add an edge reader command for the UndirEdgeReader.
  1.1523 -    void readEdge(const std::string& name, Edge& item) {
  1.1524 -      if (edgeReaders.find(name) != edgeReaders.end()) {
  1.1525 -	ErrorMessage msg;
  1.1526 -	msg << "Multiple read rule for edge: " << name;
  1.1527 -	throw IOParameterError(msg.message());
  1.1528 -      }
  1.1529 -      edgeReaders.insert(make_pair(name, &item));
  1.1530 -    }
  1.1531 -
  1.1532 -  protected:
  1.1533 -
  1.1534 -    /// \brief Gives back true when the SectionReader can process 
  1.1535 -    /// the section with the given header line.
  1.1536 -    ///
  1.1537 -    /// It gives back true when the header line start with \c \@edges,
  1.1538 -    /// and the header line's id and the reader's id are the same.
  1.1539 -    virtual bool header(const std::string& line) {
  1.1540 -      std::istringstream ls(line);
  1.1541 -      std::string command;
  1.1542 -      std::string name;
  1.1543 -      ls >> command >> name;
  1.1544 -      return command == "@undiredges" && name == id;
  1.1545 -    }
  1.1546 -
  1.1547 -    /// \brief Reader function of the section.
  1.1548 -    ///
  1.1549 -    /// It reads the content of the section.
  1.1550 -    virtual void read(std::istream& is) {
  1.1551 -      std::string line;
  1.1552 -      while (getline(is, line)) {
  1.1553 -	std::istringstream ls(line);
  1.1554 -	std::string id;
  1.1555 -	ls >> id;
  1.1556 -	{
  1.1557 -	  typename UndirEdgeReaders::iterator it = undirEdgeReaders.find(id);
  1.1558 -	  if (it != undirEdgeReaders.end()) {
  1.1559 -	    *(it->second) = undirEdgeIdReader->read(ls); 
  1.1560 -	    break;
  1.1561 -	  }	
  1.1562 -	} {
  1.1563 -	  typename EdgeReaders::iterator it = edgeReaders.find(id);
  1.1564 -	  if (it != edgeReaders.end()) {
  1.1565 -	    *(it->second) = edgeIdReader->read(ls); 
  1.1566 -	    break;
  1.1567 -	  }	
  1.1568 -	}
  1.1569 -      }
  1.1570 -    }
  1.1571 -    
  1.1572 -  private:
  1.1573 -
  1.1574 -    std::string id;
  1.1575 -
  1.1576 -    typedef std::map<std::string, UndirEdge*> UndirEdgeReaders;
  1.1577 -    UndirEdgeReaders undirEdgeReaders;
  1.1578 -    std::auto_ptr<IdReaderBase<UndirEdge> > undirEdgeIdReader;
  1.1579 -
  1.1580 -    typedef std::map<std::string, Edge*> EdgeReaders;
  1.1581 -    EdgeReaders edgeReaders;
  1.1582 -    std::auto_ptr<IdReaderBase<Edge> > edgeIdReader;
  1.1583 -  };
  1.1584 -
  1.1585 -  /// \ingroup io_group
  1.1586 -  /// \brief SectionReader for attributes.
  1.1587 -  ///
  1.1588 -  /// The lemon format can store multiple attribute set. Each set has
  1.1589 -  /// the header line \c \@attributes \c attributeset_id, but the 
  1.1590 -  /// attributeset_id may be empty.
  1.1591 -  ///
  1.1592 -  /// The attributeset section contains several lines. Each of them starts
  1.1593 -  /// with an attribute and then a the value for the id.
  1.1594 -  ///
  1.1595 -  /// \relates LemonReader
  1.1596 -  template <typename _Traits = DefaultReaderTraits>
  1.1597 -  class AttributeReader : public CommonSectionReaderBase {
  1.1598 -    typedef CommonSectionReaderBase Parent;
  1.1599 -    typedef _Traits Traits; 
  1.1600 -  public:
  1.1601 -    /// \brief Constructor.
  1.1602 -    ///
  1.1603 -    /// Constructor for AttributeReader. It creates the AttributeReader and
  1.1604 -    /// attach it into the given LemonReader. The reader process a section
  1.1605 -    /// only if the \c section_id and the \c _id are the same.
  1.1606 -    AttributeReader(LemonReader& _reader, 
  1.1607 -		    const std::string& _id = std::string()) 
  1.1608 -      : Parent(_reader), id(_id) {}
  1.1609 -
  1.1610 -    /// \brief Destructor.
  1.1611 -    ///
  1.1612 -    /// Destructor for AttributeReader.
  1.1613 -    virtual ~AttributeReader() {
  1.1614 -      for (typename Readers::iterator it = readers.begin(); 
  1.1615 -	   it != readers.end(); ++it) {
  1.1616 -	delete it->second;
  1.1617 -      }
  1.1618 -    }
  1.1619 -
  1.1620 -  private:
  1.1621 -    AttributeReader(const AttributeReader&);
  1.1622 -    void operator=(AttributeReader&);
  1.1623 -
  1.1624 -  public:
  1.1625 -    /// \brief Add an attribute reader command for the reader.
  1.1626 -    ///
  1.1627 -    /// Add an attribute reader command for the reader.
  1.1628 -    template <typename Value>
  1.1629 -    AttributeReader& readAttribute(const std::string& id, Value& value) {
  1.1630 -      return readAttribute<typename Traits::template Reader<Value> >
  1.1631 -	(id, value);
  1.1632 -    }
  1.1633 -
  1.1634 -    /// \brief Add an attribute reader command for the reader.
  1.1635 -    ///
  1.1636 -    /// Add an attribute reader command for the reader.
  1.1637 -    template <typename Reader, typename Value>
  1.1638 -    AttributeReader& readAttribute(const std::string& name, Value& value,
  1.1639 -				   const Reader& reader = Reader()) {
  1.1640 -      if (readers.find(name) != readers.end()) {
  1.1641 -	ErrorMessage msg;
  1.1642 -	msg << "Multiple read rule for attribute: " << name;
  1.1643 -	throw IOParameterError(msg.message());
  1.1644 -      }
  1.1645 -      readers.insert(make_pair(name, new ValueReader<Value, Reader>
  1.1646 -      			       (value, reader)));
  1.1647 -      return *this;
  1.1648 -    }
  1.1649 -
  1.1650 -  protected:
  1.1651 -
  1.1652 -    /// \brief Gives back true when the SectionReader can process 
  1.1653 -    /// the section with the given header line.
  1.1654 -    ///
  1.1655 -    /// It gives back true when the header line start with \c \@attributes,
  1.1656 -    /// and the header line's id and the attributeset's id are the same.
  1.1657 -    bool header(const std::string& line) {
  1.1658 -      std::istringstream ls(line);
  1.1659 -      std::string command;
  1.1660 -      std::string name;
  1.1661 -      ls >> command >> name;
  1.1662 -      return command == "@attributes" && name == id;
  1.1663 -    }
  1.1664 -
  1.1665 -    /// \brief Reader function of the section.
  1.1666 -    ///
  1.1667 -    /// It reads the content of the section.
  1.1668 -    void read(std::istream& is) {
  1.1669 -      std::string line;
  1.1670 -      while (getline(is, line)) {
  1.1671 -	std::istringstream ls(line);
  1.1672 -	std::string id;
  1.1673 -	ls >> id;
  1.1674 -	typename Readers::iterator it = readers.find(id);
  1.1675 -	if (it != readers.end()) {
  1.1676 -	  it->second->read(ls);
  1.1677 -	}
  1.1678 -      }
  1.1679 -    }    
  1.1680 -
  1.1681 -  private:
  1.1682 -    std::string id;
  1.1683 -
  1.1684 -    typedef std::map<std::string, ValueReaderBase*> Readers;
  1.1685 -    Readers readers;  
  1.1686 -  };
  1.1687 -
  1.1688 -  /// \ingroup io_group
  1.1689 -  /// \brief SectionReader for retrieve what is in the file.
  1.1690 -  ///
  1.1691 -  /// SectionReader for retrieve what is in the file. If you want
  1.1692 -  /// to know which sections, maps and items are in the file
  1.1693 -  /// use the next code:
  1.1694 -  /// \code
  1.1695 -  /// LemonReader reader("input.lgf");
  1.1696 -  /// ContentReader content(reader);
  1.1697 -  /// reader.run();
  1.1698 -  /// \endcode
  1.1699 -  class ContentReader : public LemonReader::SectionReader {
  1.1700 -    typedef LemonReader::SectionReader Parent;
  1.1701 -  public:
  1.1702 -    /// \brief Constructor.
  1.1703 -    ///
  1.1704 -    /// Constructor for
  1.1705 -    ContentReader(LemonReader& _reader) : Parent(_reader) {}
  1.1706 -
  1.1707 -    /// \brief Desctructor.
  1.1708 -    ///
  1.1709 -    /// Desctructor.
  1.1710 -    virtual ~ContentReader() {}
  1.1711 -
  1.1712 -    /// \brief Gives back how many nodesets are in the file.
  1.1713 -    ///
  1.1714 -    /// Gives back how many nodesets are in the file.
  1.1715 -    int nodeSetNum() const {
  1.1716 -      return nodesets.size();
  1.1717 -    }
  1.1718 -
  1.1719 -    /// \brief Gives back the name of nodeset on the indiced position.
  1.1720 -    ///
  1.1721 -    /// Gives back the name of nodeset on the indiced position.
  1.1722 -    std::string nodeSetName(int index) const {
  1.1723 -      return nodesets[index].name;
  1.1724 -    }
  1.1725 -
  1.1726 -    /// \brief Gives back the map names of nodeset on the indiced position.
  1.1727 -    ///
  1.1728 -    /// Gives back the map names of nodeset on the indiced position.
  1.1729 -    const std::vector<std::string>& nodeSetMaps(int index) const {
  1.1730 -      return nodesets[index].items;
  1.1731 -    }
  1.1732 -
  1.1733 -    /// \brief Gives back how many edgesets are in the file.
  1.1734 -    ///
  1.1735 -    /// Gives back how many edgesets are in the file.
  1.1736 -    int edgeSetNum() const {
  1.1737 -      return edgesets.size();
  1.1738 -    }
  1.1739 -
  1.1740 -    /// \brief Gives back the name of edgeset on the indiced position.
  1.1741 -    ///
  1.1742 -    /// Gives back the name of edgeset on the indiced position.
  1.1743 -    std::string edgeSetName(int index) const {
  1.1744 -      return edgesets[index].name;
  1.1745 -    }
  1.1746 -
  1.1747 -    /// \brief Gives back the map names of edgeset on the indiced position.
  1.1748 -    ///
  1.1749 -    /// Gives back the map names of edgeset on the indiced position.
  1.1750 -    const std::vector<std::string>& edgeSetMaps(int index) const {
  1.1751 -      return edgesets[index].items;
  1.1752 -    }
  1.1753 -
  1.1754 -    /// \brief Gives back how many undirected edgesets are in the file.
  1.1755 -    ///
  1.1756 -    /// Gives back how many undirected edgesets are in the file.
  1.1757 -    int undirEdgeSetNum() const {
  1.1758 -      return undiredgesets.size();
  1.1759 -    }
  1.1760 -
  1.1761 -    /// \brief Gives back the name of undirected edgeset on the indiced 
  1.1762 -    /// position.
  1.1763 -    ///
  1.1764 -    /// Gives back the name of undirected edgeset on the indiced position.
  1.1765 -    std::string undirEdgeSetName(int index) const {
  1.1766 -      return undiredgesets[index].name;
  1.1767 -    }
  1.1768 -
  1.1769 -    /// \brief Gives back the map names of undirected edgeset on the indiced 
  1.1770 -    /// position.
  1.1771 -    ///
  1.1772 -    /// Gives back the map names of undirected edgeset on the indiced position.
  1.1773 -    const std::vector<std::string>& undirEdgeSetMaps(int index) const {
  1.1774 -      return undiredgesets[index].items;
  1.1775 -    }
  1.1776 -
  1.1777 -    /// \brief Gives back how many labeled nodes section are in the file.
  1.1778 -    ///
  1.1779 -    /// Gives back how many labeled nodes section are in the file.
  1.1780 -    int nodesNum() const {
  1.1781 -      return nodes.size();
  1.1782 -    }
  1.1783 -
  1.1784 -    /// \brief Gives back the name of labeled nodes section on the indiced 
  1.1785 -    /// position.
  1.1786 -    ///
  1.1787 -    /// Gives back the name of labeled nodes section on the indiced position.
  1.1788 -    std::string nodesName(int index) const {
  1.1789 -      return nodes[index].name;
  1.1790 -    }
  1.1791 -
  1.1792 -    /// \brief Gives back the names of the labeled nodes in the indiced 
  1.1793 -    /// section.
  1.1794 -    ///
  1.1795 -    /// Gives back the names of the labeled nodes in the indiced section.
  1.1796 -    const std::vector<std::string>& nodesItems(int index) const {
  1.1797 -      return nodes[index].items;
  1.1798 -    }
  1.1799 -
  1.1800 -    /// \brief Gives back how many labeled edges section are in the file.
  1.1801 -    ///
  1.1802 -    /// Gives back how many labeled edges section are in the file.
  1.1803 -    int edgesNum() const {
  1.1804 -      return edges.size();
  1.1805 -    }
  1.1806 -
  1.1807 -    /// \brief Gives back the name of labeled edges section on the indiced 
  1.1808 -    /// position.
  1.1809 -    ///
  1.1810 -    /// Gives back the name of labeled edges section on the indiced position.
  1.1811 -    std::string edgesName(int index) const {
  1.1812 -      return edges[index].name;
  1.1813 -    }
  1.1814 -
  1.1815 -    /// \brief Gives back the names of the labeled edges in the indiced 
  1.1816 -    /// section.
  1.1817 -    ///
  1.1818 -    /// Gives back the names of the labeled edges in the indiced section.
  1.1819 -    const std::vector<std::string>& edgesItems(int index) const {
  1.1820 -      return edges[index].items;
  1.1821 -    }
  1.1822 - 
  1.1823 -    /// \brief Gives back how many labeled undirected edges section are 
  1.1824 -    /// in the file.
  1.1825 -    ///
  1.1826 -    /// Gives back how many labeled undirected edges section are in the file.
  1.1827 -    int undirEdgesNum() const {
  1.1828 -      return undiredges.size();
  1.1829 -    }
  1.1830 -
  1.1831 -    /// \brief Gives back the name of labeled undirected edges section 
  1.1832 -    /// on the indiced position.
  1.1833 -    ///
  1.1834 -    /// Gives back the name of labeled undirected edges section on the 
  1.1835 -    /// indiced position.
  1.1836 -    std::string undirEdgesName(int index) const {
  1.1837 -      return undiredges[index].name;
  1.1838 -    }
  1.1839 -
  1.1840 -    /// \brief Gives back the names of the labeled undirected edges in 
  1.1841 -    /// the indiced section.
  1.1842 -    ///
  1.1843 -    /// Gives back the names of the labeled undirected edges in the 
  1.1844 -    /// indiced section.
  1.1845 -    const std::vector<std::string>& undirEdgesItems(int index) const {
  1.1846 -      return undiredges[index].items;
  1.1847 -    }
  1.1848 -
  1.1849 - 
  1.1850 -    /// \brief Gives back how many attributes section are in the file.
  1.1851 -    ///
  1.1852 -    /// Gives back how many attributes section are in the file.
  1.1853 -    int attributesNum() const {
  1.1854 -      return attributes.size();
  1.1855 -    }
  1.1856 -
  1.1857 -    /// \brief Gives back the name of attributes section on the indiced 
  1.1858 -    /// position.
  1.1859 -    ///
  1.1860 -    /// Gives back the name of attributes section on the indiced position.
  1.1861 -    std::string attributesName(int index) const {
  1.1862 -      return attributes[index].name;
  1.1863 -    }
  1.1864 -
  1.1865 -    /// \brief Gives back the names of the attributes in the indiced section.
  1.1866 -    ///
  1.1867 -    /// Gives back the names of the attributes in the indiced section.
  1.1868 -    const std::vector<std::string>& attributesItems(int index) const {
  1.1869 -      return attributes[index].items;
  1.1870 -    }
  1.1871 -
  1.1872 -    const std::vector<std::string>& otherSections() const {
  1.1873 -      return sections;
  1.1874 -    }
  1.1875 -
  1.1876 -  protected:
  1.1877 -    
  1.1878 -    /// \brief Gives back true when the SectionReader can process 
  1.1879 -    /// the section with the given header line.
  1.1880 -    ///
  1.1881 -    /// It gives back true when the section is common section.
  1.1882 -    bool header(const std::string& line) {
  1.1883 -      std::istringstream ls(line);
  1.1884 -      std::string command, name;
  1.1885 -      ls >> command >> name;
  1.1886 -      if (command == "@nodeset") {
  1.1887 -	current = command;
  1.1888 -	nodesets.push_back(SectionInfo(name));
  1.1889 -      } else if (command == "@edgeset") {
  1.1890 -	current = command;
  1.1891 -	edgesets.push_back(SectionInfo(name));
  1.1892 -      } else if (command == "@undiredgeset") {
  1.1893 -	current = command;
  1.1894 -	undiredgesets.push_back(SectionInfo(name));
  1.1895 -      } else if (command == "@nodes") {
  1.1896 -	current = command;
  1.1897 -	nodes.push_back(SectionInfo(name));
  1.1898 -      } else if (command == "@edges") {
  1.1899 -	current = command;
  1.1900 -	edges.push_back(SectionInfo(name));
  1.1901 -      } else if (command == "@undiredges") {
  1.1902 -	current = command;
  1.1903 -	undiredges.push_back(SectionInfo(name));
  1.1904 -      } else if (command == "@attributes") {
  1.1905 -	current = command;
  1.1906 -	attributes.push_back(SectionInfo(name));
  1.1907 -      } else {
  1.1908 -	sections.push_back(line);
  1.1909 -	return false;
  1.1910 -      }
  1.1911 -      return true;
  1.1912 -    }
  1.1913 -
  1.1914 -    /// \brief Retrieve the items from various sections.
  1.1915 -    ///
  1.1916 -    /// Retrieve the items from various sections.
  1.1917 -    void read(std::istream& is) {
  1.1918 -      if (current == "@nodeset") {
  1.1919 -	readMapNames(is, nodesets.back().items);
  1.1920 -      } else if (current == "@edgeset") {
  1.1921 -	readMapNames(is, edgesets.back().items);
  1.1922 -      } else if (current == "@undiredgeset") {
  1.1923 -	readMapNames(is, undiredgesets.back().items);
  1.1924 -      } else if (current == "@nodes") {
  1.1925 -	readItemNames(is, nodes.back().items);
  1.1926 -      } else if (current == "@edges") {
  1.1927 -	readItemNames(is, edges.back().items);
  1.1928 -      } else if (current == "@undiredges") {
  1.1929 -	readItemNames(is, undiredges.back().items);
  1.1930 -      } else if (current == "@attributes") {
  1.1931 -	readItemNames(is, attributes.back().items);
  1.1932 -      }
  1.1933 -    }    
  1.1934 -
  1.1935 -  private:
  1.1936 -
  1.1937 -    void readMapNames(std::istream& is, std::vector<std::string>& maps) {
  1.1938 -      std::string line, id;
  1.1939 -      std::getline(is, line);
  1.1940 -      std::istringstream ls(line);
  1.1941 -      while (ls >> id) {
  1.1942 -	maps.push_back(id);
  1.1943 -      }
  1.1944 -      while (getline(is, line));
  1.1945 -    }
  1.1946 -
  1.1947 -    void readItemNames(std::istream& is, std::vector<std::string>& maps) {
  1.1948 -      std::string line, id;
  1.1949 -      while (std::getline(is, line)) {
  1.1950 -	std::istringstream ls(line);
  1.1951 -	ls >> id;
  1.1952 -	maps.push_back(id);
  1.1953 -      }
  1.1954 -    }
  1.1955 -
  1.1956 -    struct SectionInfo {
  1.1957 -      std::string name;
  1.1958 -      std::vector<std::string> items;
  1.1959 -
  1.1960 -      SectionInfo(const std::string& _name) : name(_name) {}
  1.1961 -    };
  1.1962 -
  1.1963 -    std::vector<SectionInfo> nodesets;
  1.1964 -    std::vector<SectionInfo> edgesets;
  1.1965 -    std::vector<SectionInfo> undiredgesets;
  1.1966 -
  1.1967 -    std::vector<SectionInfo> nodes;
  1.1968 -    std::vector<SectionInfo> edges;
  1.1969 -    std::vector<SectionInfo> undiredges;
  1.1970 -
  1.1971 -    std::vector<SectionInfo> attributes;
  1.1972 -
  1.1973 -    std::vector<std::string> sections;
  1.1974 -
  1.1975 -    std::string current;
  1.1976 -
  1.1977 -  };
  1.1978 -
  1.1979 -}
  1.1980 -#endif