lemon/lemon_reader.h
changeset 1845 f8bbfed86036
parent 1746 874e4bc21435
child 1846 6b4e38acef1c
     1.1 --- a/lemon/lemon_reader.h	Sat Dec 03 18:15:43 2005 +0000
     1.2 +++ b/lemon/lemon_reader.h	Sat Dec 03 18:17:29 2005 +0000
     1.3 @@ -45,6 +45,18 @@
     1.4  
     1.5    namespace _reader_bits {
     1.6  
     1.7 +    template <typename T>
     1.8 +    bool operator<(T, T) {
     1.9 +      throw DataFormatError("Id is not comparable");
    1.10 +    }
    1.11 +
    1.12 +    template <typename T>
    1.13 +    struct Less {
    1.14 +      bool operator()(const T& p, const T& q) const {
    1.15 +	return p < q;
    1.16 +      }
    1.17 +    };
    1.18 +
    1.19      template <typename Item>
    1.20      class ItemIdReader {
    1.21      public:
    1.22 @@ -83,18 +95,6 @@
    1.23        };
    1.24  
    1.25      };
    1.26 -  
    1.27 -    template <typename T>
    1.28 -    bool operator<(T, T) {
    1.29 -      throw DataFormatError("Id is not comparable");
    1.30 -    }
    1.31 -
    1.32 -    template <typename T>
    1.33 -    struct Less {
    1.34 -      bool operator()(const T& p, const T& q) const {
    1.35 -	return p < q;
    1.36 -      }
    1.37 -    };
    1.38  
    1.39      template <typename Map>
    1.40      struct Ref { typedef Map& Type; };
    1.41 @@ -198,6 +198,253 @@
    1.42        typedef const YMap<Map>& Type;
    1.43      };
    1.44  
    1.45 +
    1.46 +    template <typename _Item>
    1.47 +    class MapReaderBase;
    1.48 +    
    1.49 +    template <typename _Item>
    1.50 +    class MapInverterBase : public MapReaderBase<_Item> {
    1.51 +    public:
    1.52 +      typedef _Item Item;
    1.53 +      virtual void read(std::istream&, const Item&) = 0;
    1.54 +      virtual Item read(std::istream&) const = 0;
    1.55 +
    1.56 +      virtual MapInverterBase<_Item>* getInverter() {
    1.57 +	return this;
    1.58 +      }
    1.59 +    };
    1.60 +
    1.61 +    template <typename _Item, typename _Map, typename _Reader>
    1.62 +    class MapReaderInverter : public MapInverterBase<_Item> {
    1.63 +    public:
    1.64 +      typedef _Item Item;
    1.65 +      typedef _Reader Reader;
    1.66 +      typedef typename Reader::Value Value;
    1.67 +      typedef _Map Map;
    1.68 +      typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
    1.69 +
    1.70 +      typename _reader_bits::Ref<Map>::Type map;
    1.71 +      Reader reader;
    1.72 +      Inverse inverse;
    1.73 +
    1.74 +      MapReaderInverter(typename _reader_bits::Arg<Map>::Type _map,
    1.75 +			const Reader& _reader) 
    1.76 +	: map(_map), reader(_reader) {}
    1.77 +
    1.78 +      virtual ~MapReaderInverter() {}
    1.79 +
    1.80 +      virtual void read(std::istream& is, const Item& item) {
    1.81 +	Value value;
    1.82 +	reader.read(is, value);
    1.83 +	map.set(item, value);
    1.84 +	typename Inverse::iterator it = inverse.find(value);
    1.85 +	if (it == inverse.end()) {
    1.86 +	  inverse.insert(std::make_pair(value, item));
    1.87 +	} else {
    1.88 +	  throw DataFormatError("Multiple ID occurence");
    1.89 +	}
    1.90 +      }
    1.91 +
    1.92 +      virtual Item read(std::istream& is) const {
    1.93 +	Value value;
    1.94 +	reader.read(is, value);	
    1.95 +	typename Inverse::const_iterator it = inverse.find(value);
    1.96 +	if (it != inverse.end()) {
    1.97 +	  return it->second;
    1.98 +	} else {
    1.99 +	  throw DataFormatError("Invalid ID error");
   1.100 +	}
   1.101 +      }      
   1.102 +    };
   1.103 +
   1.104 +    template <typename _Item, typename _Reader>
   1.105 +    class SkipReaderInverter : public MapInverterBase<_Item> {
   1.106 +    public:
   1.107 +      typedef _Item Item;
   1.108 +      typedef _Reader Reader;
   1.109 +      typedef typename Reader::Value Value;
   1.110 +      typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
   1.111 +
   1.112 +      Reader reader;
   1.113 +
   1.114 +      SkipReaderInverter(const Reader& _reader) 
   1.115 +	: reader(_reader) {}
   1.116 +
   1.117 +      virtual ~SkipReaderInverter() {}
   1.118 +
   1.119 +      virtual void read(std::istream& is, const Item& item) {
   1.120 +	Value value;
   1.121 +	reader.read(is, value);
   1.122 +	typename Inverse::iterator it = inverse.find(value);
   1.123 +	if (it == inverse.end()) {
   1.124 +	  inverse.insert(std::make_pair(value, item));
   1.125 +	} else {
   1.126 +	  throw DataFormatError("Multiple ID occurence error");
   1.127 +	}
   1.128 +      }
   1.129 +
   1.130 +      virtual Item read(std::istream& is) const {
   1.131 +	Value value;
   1.132 +	reader.read(is, value);	
   1.133 +	typename Inverse::const_iterator it = inverse.find(value);
   1.134 +	if (it != inverse.end()) {
   1.135 +	  return it->second;
   1.136 +	} else {
   1.137 +	  throw DataFormatError("Invalid ID error");
   1.138 +	}
   1.139 +      }
   1.140 +
   1.141 +    private:
   1.142 +      Inverse inverse;
   1.143 +    };
   1.144 +
   1.145 +    template <typename _Item>    
   1.146 +    class MapReaderBase {
   1.147 +    public:
   1.148 +      typedef _Item Item;
   1.149 +
   1.150 +      MapReaderBase() { _touched = false; }
   1.151 +      
   1.152 +      void touch() { _touched = true; }
   1.153 +      bool touched() const { return _touched; }
   1.154 +
   1.155 +      virtual ~MapReaderBase() {}
   1.156 +
   1.157 +      virtual void read(std::istream& is, const Item& item) = 0;
   1.158 +      virtual MapInverterBase<_Item>* getInverter() = 0;
   1.159 +
   1.160 +    private:      
   1.161 +      bool _touched;
   1.162 +
   1.163 +    };
   1.164 +
   1.165 +    template <typename _Item, typename _Map, typename _Reader>
   1.166 +    class MapReader : public MapReaderBase<_Item> {
   1.167 +    public:
   1.168 +      typedef _Map Map;
   1.169 +      typedef _Reader Reader;
   1.170 +      typedef typename Reader::Value Value;
   1.171 +      typedef _Item Item;
   1.172 +      
   1.173 +      typename _reader_bits::Ref<Map>::Type map;
   1.174 +      Reader reader;
   1.175 +
   1.176 +      MapReader(typename _reader_bits::Arg<Map>::Type _map, 
   1.177 +		const Reader& _reader) 
   1.178 +	: map(_map), reader(_reader) {}
   1.179 +
   1.180 +      virtual ~MapReader() {}
   1.181 +
   1.182 +      virtual void read(std::istream& is, const Item& item) {
   1.183 +	Value value;
   1.184 +	reader.read(is, value);
   1.185 +	map.set(item, value);
   1.186 +      }
   1.187 +
   1.188 +      virtual MapInverterBase<_Item>* getInverter() {
   1.189 +	return new MapReaderInverter<Item, Map, Reader>(map, reader);
   1.190 +      }
   1.191 +    };
   1.192 +
   1.193 +
   1.194 +    template <typename _Item, typename _Reader>
   1.195 +    class SkipReader : public MapReaderBase<_Item> {
   1.196 +    public:
   1.197 +      typedef _Reader Reader;
   1.198 +      typedef typename Reader::Value Value;
   1.199 +      typedef _Item Item;
   1.200 +
   1.201 +      Reader reader;
   1.202 +      SkipReader(const Reader& _reader) : reader(_reader) {}
   1.203 +
   1.204 +      virtual ~SkipReader() {}
   1.205 +
   1.206 +      virtual void read(std::istream& is, const Item&) {
   1.207 +	Value value;
   1.208 +	reader.read(is, value);
   1.209 +      }      
   1.210 +
   1.211 +      virtual MapInverterBase<Item>* getInverter() {
   1.212 +	return new SkipReaderInverter<Item, Reader>(reader);
   1.213 +      }
   1.214 +    };
   1.215 +
   1.216 +    template <typename _Item>
   1.217 +    class IdReaderBase {
   1.218 +    public:
   1.219 +      typedef _Item Item;
   1.220 +      virtual ~IdReaderBase() {}
   1.221 +      virtual Item read(std::istream& is) const = 0;
   1.222 +      virtual bool isIdReader() const = 0;
   1.223 +    };
   1.224 +
   1.225 +    template <typename _Item, typename _BoxedIdReader>
   1.226 +    class IdReader : public IdReaderBase<_Item> {
   1.227 +    public:
   1.228 +      typedef _Item Item;
   1.229 +      typedef _BoxedIdReader BoxedIdReader;
   1.230 +      
   1.231 +      const BoxedIdReader& boxedIdReader;
   1.232 +
   1.233 +      IdReader(const BoxedIdReader& _boxedIdReader) 
   1.234 +	: boxedIdReader(_boxedIdReader) {}
   1.235 +
   1.236 +      virtual Item read(std::istream& is) const {
   1.237 +	Item item;
   1.238 +	boxedIdReader.readId(is, item);
   1.239 +	return item;
   1.240 +      }
   1.241 +
   1.242 +      virtual bool isIdReader() const {
   1.243 +	return boxedIdReader.isIdReader();
   1.244 +      }
   1.245 +    };
   1.246 +
   1.247 +    template <typename _Item>
   1.248 +    class ItemStore {
   1.249 +    public:
   1.250 +
   1.251 +      typedef _Item Item;
   1.252 +
   1.253 +      ItemStore(Item& _item) : item(&_item) { 
   1.254 +	_touched = false; 
   1.255 +      }
   1.256 +      
   1.257 +      void touch() { _touched = true; }
   1.258 +      bool touched() const { return _touched; }
   1.259 +
   1.260 +      void read(const Item& _item) {
   1.261 +	*item = _item;
   1.262 +      }
   1.263 +      
   1.264 +    private:
   1.265 +      Item* item;
   1.266 +      bool _touched;
   1.267 +    };
   1.268 +
   1.269 +    class ValueReaderBase {
   1.270 +    public:
   1.271 +      virtual void read(std::istream&) {};
   1.272 +      virtual ~ValueReaderBase() {}
   1.273 +    };
   1.274 +
   1.275 +    template <typename _Value, typename _Reader>
   1.276 +    class ValueReader : public ValueReaderBase {
   1.277 +    public:
   1.278 +      typedef _Value Value;
   1.279 +      typedef _Reader Reader;
   1.280 +
   1.281 +      ValueReader(Value& _value, const Reader& _reader)
   1.282 + 	: value(_value), reader(_reader) {}
   1.283 +
   1.284 +      virtual void read(std::istream& is) {
   1.285 +	reader.read(is, value);
   1.286 +      }
   1.287 +    private:
   1.288 +      Value& value;
   1.289 +      Reader reader;
   1.290 +    };
   1.291 +
   1.292    }
   1.293  
   1.294    /// \ingroup io_group
   1.295 @@ -469,237 +716,6 @@
   1.296  
   1.297    };
   1.298  
   1.299 -  /// \brief Helper class for implementing the common SectionReaders.
   1.300 -  ///
   1.301 -  /// Helper class for implementing the common SectionReaders.
   1.302 -  class CommonSectionReaderBase : public LemonReader::SectionReader {
   1.303 -    typedef LemonReader::SectionReader Parent;
   1.304 -  protected:
   1.305 -    
   1.306 -    /// \brief Constructor for CommonSectionReaderBase.
   1.307 -    ///
   1.308 -    /// Constructor for CommonSectionReaderBase. It attach this reader to
   1.309 -    /// the given LemonReader.
   1.310 -    CommonSectionReaderBase(LemonReader& _reader) 
   1.311 -      : Parent(_reader) {}
   1.312 -
   1.313 -    template <typename _Item>
   1.314 -    class ReaderBase;
   1.315 -    
   1.316 -    template <typename _Item>
   1.317 -    class InverterBase : public ReaderBase<_Item> {
   1.318 -    public:
   1.319 -      typedef _Item Item;
   1.320 -      virtual void read(std::istream&, const Item&) = 0;
   1.321 -      virtual Item read(std::istream&) const = 0;
   1.322 -
   1.323 -      virtual InverterBase<_Item>* getInverter() {
   1.324 -	return this;
   1.325 -      }
   1.326 -    };
   1.327 -
   1.328 -    template <typename _Item, typename _Map, typename _Reader>
   1.329 -    class MapReaderInverter : public InverterBase<_Item> {
   1.330 -    public:
   1.331 -      typedef _Item Item;
   1.332 -      typedef _Reader Reader;
   1.333 -      typedef typename Reader::Value Value;
   1.334 -      typedef _Map Map;
   1.335 -      typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
   1.336 -
   1.337 -      typename _reader_bits::Ref<Map>::Type map;
   1.338 -      Reader reader;
   1.339 -      Inverse inverse;
   1.340 -
   1.341 -      MapReaderInverter(typename _reader_bits::Arg<Map>::Type _map,
   1.342 -			const Reader& _reader) 
   1.343 -	: map(_map), reader(_reader) {}
   1.344 -
   1.345 -      virtual ~MapReaderInverter() {}
   1.346 -
   1.347 -      virtual void read(std::istream& is, const Item& item) {
   1.348 -	Value value;
   1.349 -	reader.read(is, value);
   1.350 -	map.set(item, value);
   1.351 -	typename Inverse::iterator it = inverse.find(value);
   1.352 -	if (it == inverse.end()) {
   1.353 -	  inverse.insert(std::make_pair(value, item));
   1.354 -	} else {
   1.355 -	  throw DataFormatError("Multiple ID occurence");
   1.356 -	}
   1.357 -      }
   1.358 -
   1.359 -      virtual Item read(std::istream& is) const {
   1.360 -	Value value;
   1.361 -	reader.read(is, value);	
   1.362 -	typename Inverse::const_iterator it = inverse.find(value);
   1.363 -	if (it != inverse.end()) {
   1.364 -	  return it->second;
   1.365 -	} else {
   1.366 -	  throw DataFormatError("Invalid ID error");
   1.367 -	}
   1.368 -      }      
   1.369 -    };
   1.370 -
   1.371 -    template <typename _Item, typename _Reader>
   1.372 -    class SkipReaderInverter : public InverterBase<_Item> {
   1.373 -    public:
   1.374 -      typedef _Item Item;
   1.375 -      typedef _Reader Reader;
   1.376 -      typedef typename Reader::Value Value;
   1.377 -      typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
   1.378 -
   1.379 -      Reader reader;
   1.380 -
   1.381 -      SkipReaderInverter(const Reader& _reader) 
   1.382 -	: reader(_reader) {}
   1.383 -
   1.384 -      virtual ~SkipReaderInverter() {}
   1.385 -
   1.386 -      virtual void read(std::istream& is, const Item& item) {
   1.387 -	Value value;
   1.388 -	reader.read(is, value);
   1.389 -	typename Inverse::iterator it = inverse.find(value);
   1.390 -	if (it == inverse.end()) {
   1.391 -	  inverse.insert(std::make_pair(value, item));
   1.392 -	} else {
   1.393 -	  throw DataFormatError("Multiple ID occurence error");
   1.394 -	}
   1.395 -      }
   1.396 -
   1.397 -      virtual Item read(std::istream& is) const {
   1.398 -	Value value;
   1.399 -	reader.read(is, value);	
   1.400 -	typename Inverse::const_iterator it = inverse.find(value);
   1.401 -	if (it != inverse.end()) {
   1.402 -	  return it->second;
   1.403 -	} else {
   1.404 -	  throw DataFormatError("Invalid ID error");
   1.405 -	}
   1.406 -      }
   1.407 -
   1.408 -    private:
   1.409 -      Inverse inverse;
   1.410 -    };
   1.411 -
   1.412 -    template <typename _Item>    
   1.413 -    class ReaderBase {
   1.414 -    public:
   1.415 -      typedef _Item Item;
   1.416 -
   1.417 -      virtual ~ReaderBase() {}
   1.418 -
   1.419 -      virtual void read(std::istream& is, const Item& item) = 0;
   1.420 -      virtual InverterBase<_Item>* getInverter() = 0;
   1.421 -    };
   1.422 -
   1.423 -    template <typename _Item, typename _Map, typename _Reader>
   1.424 -    class MapReader : public ReaderBase<_Item> {
   1.425 -    public:
   1.426 -      typedef _Map Map;
   1.427 -      typedef _Reader Reader;
   1.428 -      typedef typename Reader::Value Value;
   1.429 -      typedef _Item Item;
   1.430 -      
   1.431 -      typename _reader_bits::Ref<Map>::Type map;
   1.432 -      Reader reader;
   1.433 -
   1.434 -      MapReader(typename _reader_bits::Arg<Map>::Type _map, 
   1.435 -		const Reader& _reader) 
   1.436 -	: map(_map), reader(_reader) {}
   1.437 -
   1.438 -      virtual ~MapReader() {}
   1.439 -
   1.440 -      virtual void read(std::istream& is, const Item& item) {
   1.441 -	Value value;
   1.442 -	reader.read(is, value);
   1.443 -	map.set(item, value);
   1.444 -      }
   1.445 -
   1.446 -      virtual InverterBase<_Item>* getInverter() {
   1.447 -	return new MapReaderInverter<Item, Map, Reader>(map, reader);
   1.448 -      }
   1.449 -    };
   1.450 -
   1.451 -
   1.452 -    template <typename _Item, typename _Reader>
   1.453 -    class SkipReader : public ReaderBase<_Item> {
   1.454 -    public:
   1.455 -      typedef _Reader Reader;
   1.456 -      typedef typename Reader::Value Value;
   1.457 -      typedef _Item Item;
   1.458 -
   1.459 -      Reader reader;
   1.460 -      SkipReader(const Reader& _reader) : reader(_reader) {}
   1.461 -
   1.462 -      virtual ~SkipReader() {}
   1.463 -
   1.464 -      virtual void read(std::istream& is, const Item&) {
   1.465 -	Value value;
   1.466 -	reader.read(is, value);
   1.467 -      }      
   1.468 -
   1.469 -      virtual InverterBase<Item>* getInverter() {
   1.470 -	return new SkipReaderInverter<Item, Reader>(reader);
   1.471 -      }
   1.472 -    };
   1.473 -
   1.474 -    template <typename _Item>
   1.475 -    class IdReaderBase {
   1.476 -    public:
   1.477 -      typedef _Item Item;
   1.478 -      virtual ~IdReaderBase() {}
   1.479 -      virtual Item read(std::istream& is) const = 0;
   1.480 -      virtual bool isIdReader() const = 0;
   1.481 -    };
   1.482 -
   1.483 -    template <typename _Item, typename _BoxedIdReader>
   1.484 -    class IdReader : public IdReaderBase<_Item> {
   1.485 -    public:
   1.486 -      typedef _Item Item;
   1.487 -      typedef _BoxedIdReader BoxedIdReader;
   1.488 -      
   1.489 -      const BoxedIdReader& boxedIdReader;
   1.490 -
   1.491 -      IdReader(const BoxedIdReader& _boxedIdReader) 
   1.492 -	: boxedIdReader(_boxedIdReader) {}
   1.493 -
   1.494 -      virtual Item read(std::istream& is) const {
   1.495 -	Item item;
   1.496 -	boxedIdReader.readId(is, item);
   1.497 -	return item;
   1.498 -      }
   1.499 -
   1.500 -      virtual bool isIdReader() const {
   1.501 -	return boxedIdReader.isIdReader();
   1.502 -      }
   1.503 -    };
   1.504 -
   1.505 -    class ValueReaderBase {
   1.506 -    public:
   1.507 -      virtual void read(std::istream&) {};
   1.508 -      virtual ~ValueReaderBase() {}
   1.509 -    };
   1.510 -
   1.511 -    template <typename _Value, typename _Reader>
   1.512 -    class ValueReader : public ValueReaderBase {
   1.513 -    public:
   1.514 -      typedef _Value Value;
   1.515 -      typedef _Reader Reader;
   1.516 -
   1.517 -      ValueReader(Value& _value, const Reader& _reader)
   1.518 - 	: value(_value), reader(_reader) {}
   1.519 -
   1.520 -      virtual void read(std::istream& is) {
   1.521 -	reader.read(is, value);
   1.522 -      }
   1.523 -    private:
   1.524 -      Value& value;
   1.525 -      Reader reader;
   1.526 -    };
   1.527 -    
   1.528 -  };
   1.529 -
   1.530    /// \ingroup io_group
   1.531    /// \brief SectionReader for reading a graph's nodeset.
   1.532    ///
   1.533 @@ -718,8 +734,8 @@
   1.534    ///
   1.535    /// \relates LemonReader
   1.536    template <typename _Graph, typename _Traits = DefaultReaderTraits>
   1.537 -  class NodeSetReader : public CommonSectionReaderBase {
   1.538 -    typedef CommonSectionReaderBase Parent;
   1.539 +  class NodeSetReader : public LemonReader::SectionReader {
   1.540 +    typedef LemonReader::SectionReader Parent;
   1.541    public:
   1.542  
   1.543      typedef _Graph Graph;
   1.544 @@ -801,9 +817,10 @@
   1.545  	ErrorMessage msg;
   1.546  	msg << "Multiple read rule for node map: " << name;
   1.547  	throw IOParameterError(msg.message());
   1.548 -      }
   1.549 +      }      
   1.550        readers.insert(
   1.551 -	make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
   1.552 +        make_pair(name, new _reader_bits::
   1.553 +		  MapReader<Node, Map, Reader>(map, reader)));
   1.554        return *this;
   1.555      }
   1.556  
   1.557 @@ -820,7 +837,8 @@
   1.558  	msg << "Multiple read rule for node map: " << name;
   1.559  	throw IOParameterError(msg.message());
   1.560        }
   1.561 -      readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
   1.562 +      readers.insert(make_pair(name, new _reader_bits::
   1.563 +			       SkipReader<Node, Reader>(reader)));
   1.564        return *this;
   1.565      }
   1.566  
   1.567 @@ -843,7 +861,7 @@
   1.568      ///
   1.569      /// It reads the content of the section.
   1.570      virtual void read(std::istream& is) {
   1.571 -      std::vector<ReaderBase<Node>* > index;
   1.572 +      std::vector<_reader_bits::MapReaderBase<Node>* > index;
   1.573        std::string line;
   1.574  
   1.575        getline(is, line);
   1.576 @@ -851,6 +869,7 @@
   1.577        while (ls >> id) {
   1.578  	typename MapReaders::iterator it = readers.find(id);
   1.579  	if (it != readers.end()) {
   1.580 +	  it->second->touch();
   1.581  	  index.push_back(it->second);
   1.582  	} else {
   1.583  	  index.push_back(&skipper);
   1.584 @@ -860,6 +879,14 @@
   1.585  	  index.back() = inverter.get();
   1.586  	}
   1.587        }
   1.588 +      for (typename MapReaders::iterator it = readers.begin();
   1.589 +	   it != readers.end(); ++it) {
   1.590 +	if (!it->second->touched()) {
   1.591 +	  ErrorMessage msg;
   1.592 +	  msg << "Map not found in file: " << it->first;
   1.593 +	  throw IOParameterError(msg.message());
   1.594 +	}
   1.595 +      }
   1.596        while (getline(is, line)) {	
   1.597  	Node node = graph.addNode();
   1.598  	std::istringstream ls(line);
   1.599 @@ -889,14 +916,14 @@
   1.600  
   1.601    private:
   1.602  
   1.603 -    typedef std::map<std::string, ReaderBase<Node>*> MapReaders;
   1.604 +    typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
   1.605      MapReaders readers;
   1.606     
   1.607      Graph& graph;   
   1.608      std::string id;
   1.609 -    SkipReader<Node, DefaultSkipper> skipper;
   1.610 +    _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
   1.611  
   1.612 -    std::auto_ptr<InverterBase<Node> > inverter;
   1.613 +    std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
   1.614    };
   1.615  
   1.616    /// \ingroup io_group
   1.617 @@ -922,8 +949,8 @@
   1.618    ///
   1.619    /// \relates LemonReader
   1.620    template <typename _Graph, typename _Traits = DefaultReaderTraits>
   1.621 -  class EdgeSetReader : public CommonSectionReaderBase {
   1.622 -    typedef CommonSectionReaderBase Parent;
   1.623 +  class EdgeSetReader : public LemonReader::SectionReader {
   1.624 +    typedef LemonReader::SectionReader Parent;
   1.625    public:
   1.626  
   1.627      typedef _Graph Graph;
   1.628 @@ -948,7 +975,8 @@
   1.629  		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   1.630        : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {
   1.631        checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>();
   1.632 -      nodeIdReader.reset(new IdReader<Node, NodeIdReader>(_nodeIdReader));
   1.633 +      nodeIdReader.reset(new _reader_bits::
   1.634 +			 IdReader<Node, NodeIdReader>(_nodeIdReader));
   1.635      }
   1.636      /// \brief Destructor.
   1.637      ///
   1.638 @@ -1013,7 +1041,8 @@
   1.639  	throw IOParameterError(msg.message());
   1.640        }
   1.641        readers.insert(
   1.642 -	make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   1.643 +	make_pair(name, new _reader_bits::
   1.644 +		  MapReader<Edge, Map, Reader>(map, reader)));
   1.645        return *this;
   1.646      }
   1.647  
   1.648 @@ -1030,7 +1059,8 @@
   1.649  	msg << "Multiple read rule for edge map: " << name;
   1.650  	throw IOParameterError(msg.message());
   1.651        }
   1.652 -      readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
   1.653 +      readers.insert(make_pair(name, new _reader_bits::
   1.654 +			       SkipReader<Edge, Reader>(reader)));
   1.655        return *this;
   1.656      }
   1.657  
   1.658 @@ -1056,7 +1086,7 @@
   1.659        if (!nodeIdReader->isIdReader()) {
   1.660  	throw DataFormatError("Cannot find nodeset or ID map");
   1.661        }
   1.662 -      std::vector<ReaderBase<Edge>* > index;
   1.663 +      std::vector<_reader_bits::MapReaderBase<Edge>* > index;
   1.664        std::string line;
   1.665  
   1.666        getline(is, line);
   1.667 @@ -1065,6 +1095,7 @@
   1.668  	typename MapReaders::iterator it = readers.find(id);
   1.669  	if (it != readers.end()) {
   1.670  	  index.push_back(it->second);
   1.671 +	  it->second->touch();
   1.672  	} else {
   1.673  	  index.push_back(&skipper);
   1.674  	}
   1.675 @@ -1073,6 +1104,14 @@
   1.676  	  index.back() = inverter.get();
   1.677  	}
   1.678        }
   1.679 +      for (typename MapReaders::iterator it = readers.begin();
   1.680 +	   it != readers.end(); ++it) {
   1.681 +	if (!it->second->touched()) {
   1.682 +	  ErrorMessage msg;
   1.683 +	  msg << "Map not found in file: " << it->first;
   1.684 +	  throw IOParameterError(msg.message());
   1.685 +	}
   1.686 +      }
   1.687        while (getline(is, line)) {	
   1.688  	std::istringstream ls(line);
   1.689  	Node from = nodeIdReader->read(ls);
   1.690 @@ -1104,15 +1143,15 @@
   1.691  
   1.692    private:
   1.693  
   1.694 -    typedef std::map<std::string, ReaderBase<Edge>*> MapReaders;
   1.695 +    typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
   1.696      MapReaders readers;
   1.697     
   1.698      Graph& graph;   
   1.699      std::string id;
   1.700 -    SkipReader<Edge, DefaultSkipper> skipper;
   1.701 +    _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
   1.702  
   1.703 -    std::auto_ptr<InverterBase<Edge> > inverter;
   1.704 -    std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
   1.705 +    std::auto_ptr<_reader_bits::MapInverterBase<Edge> > inverter;
   1.706 +    std::auto_ptr<_reader_bits::IdReaderBase<Node> > nodeIdReader;
   1.707    };
   1.708  
   1.709    /// \ingroup io_group
   1.710 @@ -1143,8 +1182,8 @@
   1.711    ///
   1.712    /// \relates LemonReader
   1.713    template <typename _Graph, typename _Traits = DefaultReaderTraits>
   1.714 -  class UndirEdgeSetReader : public CommonSectionReaderBase {
   1.715 -    typedef CommonSectionReaderBase Parent;
   1.716 +  class UndirEdgeSetReader : public LemonReader::SectionReader {
   1.717 +    typedef LemonReader::SectionReader Parent;
   1.718    public:
   1.719  
   1.720      typedef _Graph Graph;
   1.721 @@ -1170,7 +1209,8 @@
   1.722  		       const DefaultSkipper& _skipper = DefaultSkipper()) 
   1.723        : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {
   1.724        checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>();
   1.725 -      nodeIdReader.reset(new IdReader<Node, NodeIdReader>(_nodeIdReader));
   1.726 +      nodeIdReader.reset(new _reader_bits::
   1.727 +			 IdReader<Node, NodeIdReader>(_nodeIdReader));
   1.728      }
   1.729      /// \brief Destructor.
   1.730      ///
   1.731 @@ -1235,7 +1275,8 @@
   1.732  	throw IOParameterError(msg.message());
   1.733        }
   1.734        readers.insert(
   1.735 -	make_pair(name, new MapReader<UndirEdge, Map, Reader>(map, reader)));
   1.736 +	make_pair(name, new _reader_bits::
   1.737 +		  MapReader<UndirEdge, Map, Reader>(map, reader)));
   1.738        return *this;
   1.739      }
   1.740  
   1.741 @@ -1252,8 +1293,8 @@
   1.742  	msg << "Multiple read rule for node map: " << name;
   1.743  	throw IOParameterError(msg.message());
   1.744        }
   1.745 -      readers.insert(make_pair(name, 
   1.746 -			       new SkipReader<UndirEdge, Reader>(reader)));
   1.747 +      readers.insert(make_pair(name, new _reader_bits::
   1.748 +			       SkipReader<UndirEdge, Reader>(reader)));
   1.749        return *this;
   1.750      }
   1.751  
   1.752 @@ -1340,7 +1381,7 @@
   1.753        if (!nodeIdReader->isIdReader()) {
   1.754  	throw DataFormatError("Cannot find nodeset or ID map");
   1.755        }
   1.756 -      std::vector<ReaderBase<UndirEdge>* > index;
   1.757 +      std::vector<_reader_bits::MapReaderBase<UndirEdge>* > index;
   1.758        std::string line;
   1.759  
   1.760        getline(is, line);
   1.761 @@ -1349,6 +1390,7 @@
   1.762  	typename MapReaders::iterator it = readers.find(id);
   1.763  	if (it != readers.end()) {
   1.764  	  index.push_back(it->second);
   1.765 +	  it->second->touch();
   1.766  	} else {
   1.767  	  index.push_back(&skipper);
   1.768  	}
   1.769 @@ -1357,6 +1399,14 @@
   1.770  	  index.back() = inverter.get();
   1.771  	}
   1.772        }
   1.773 +      for (typename MapReaders::iterator it = readers.begin();
   1.774 +	   it != readers.end(); ++it) {
   1.775 +	if (!it->second->touched()) {
   1.776 +	  ErrorMessage msg;
   1.777 +	  msg << "Map not found in file: " << it->first;
   1.778 +	  throw IOParameterError(msg.message());
   1.779 +	}
   1.780 +      }
   1.781        while (getline(is, line)) {	
   1.782  	std::istringstream ls(line);
   1.783  	Node from = nodeIdReader->read(ls);
   1.784 @@ -1408,15 +1458,16 @@
   1.785  
   1.786    private:
   1.787  
   1.788 -    typedef std::map<std::string, ReaderBase<UndirEdge>*> MapReaders;
   1.789 +    typedef std::map<std::string, 
   1.790 +		     _reader_bits::MapReaderBase<UndirEdge>*> MapReaders;
   1.791      MapReaders readers;
   1.792     
   1.793      Graph& graph;   
   1.794      std::string id;
   1.795 -    SkipReader<UndirEdge, DefaultSkipper> skipper;
   1.796 +    _reader_bits::SkipReader<UndirEdge, DefaultSkipper> skipper;
   1.797  
   1.798 -    std::auto_ptr<InverterBase<UndirEdge> > inverter;
   1.799 -    std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
   1.800 +    std::auto_ptr<_reader_bits::MapInverterBase<UndirEdge> > inverter;
   1.801 +    std::auto_ptr<_reader_bits::IdReaderBase<Node> > nodeIdReader;
   1.802    };
   1.803  
   1.804    /// \ingroup io_group
   1.805 @@ -1430,8 +1481,8 @@
   1.806    ///
   1.807    /// \relates LemonReader
   1.808    template <typename _Graph>
   1.809 -  class NodeReader : public CommonSectionReaderBase {
   1.810 -    typedef CommonSectionReaderBase Parent;
   1.811 +  class NodeReader : public LemonReader::SectionReader {
   1.812 +    typedef LemonReader::SectionReader Parent;
   1.813      typedef _Graph Graph;
   1.814      typedef typename Graph::Node Node;
   1.815    public:
   1.816 @@ -1447,7 +1498,8 @@
   1.817  	       const std::string& _id = std::string()) 
   1.818        : Parent(_reader), id(_id) {
   1.819        checkConcept<_reader_bits::ItemIdReader<Node>, _IdReader>();
   1.820 -      nodeIdReader.reset(new IdReader<Node, _IdReader>(_idReader));
   1.821 +      nodeIdReader.reset(new _reader_bits::
   1.822 +			 IdReader<Node, _IdReader>(_idReader));
   1.823      }
   1.824  
   1.825      /// \brief Destructor.
   1.826 @@ -1470,7 +1522,7 @@
   1.827  	msg << "Multiple read rule for node: " << name;
   1.828  	throw IOParameterError(msg.message());
   1.829        }
   1.830 -      readers.insert(make_pair(name, &item));
   1.831 +      readers.insert(make_pair(name, _reader_bits::ItemStore<Node>(item)));
   1.832      }
   1.833  
   1.834    protected:
   1.835 @@ -1502,18 +1554,27 @@
   1.836  	ls >> id;
   1.837  	typename NodeReaders::iterator it = readers.find(id);
   1.838  	if (it != readers.end()) {
   1.839 -	  *(it->second) = nodeIdReader->read(ls); 
   1.840 +	  it->second.read(nodeIdReader->read(ls));
   1.841 +	  it->second.touch();
   1.842  	}	
   1.843        }
   1.844 +      for (typename NodeReaders::iterator it = readers.begin();
   1.845 +	   it != readers.end(); ++it) {
   1.846 +	if (!it->second.touched()) {
   1.847 +	  ErrorMessage msg;
   1.848 +	  msg << "Node not found in file: " << it->first;
   1.849 +	  throw IOParameterError(msg.message());
   1.850 +	}
   1.851 +      }
   1.852      }
   1.853      
   1.854    private:
   1.855  
   1.856      std::string id;
   1.857  
   1.858 -    typedef std::map<std::string, Node*> NodeReaders;
   1.859 +    typedef std::map<std::string, _reader_bits::ItemStore<Node> > NodeReaders;
   1.860      NodeReaders readers;
   1.861 -    std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
   1.862 +    std::auto_ptr<_reader_bits::IdReaderBase<Node> > nodeIdReader;
   1.863    };
   1.864  
   1.865    /// \ingroup io_group
   1.866 @@ -1527,8 +1588,8 @@
   1.867    ///
   1.868    /// \relates LemonReader
   1.869    template <typename _Graph>
   1.870 -  class EdgeReader : public CommonSectionReaderBase {
   1.871 -    typedef CommonSectionReaderBase Parent;
   1.872 +  class EdgeReader : public LemonReader::SectionReader {
   1.873 +    typedef LemonReader::SectionReader Parent;
   1.874      typedef _Graph Graph;
   1.875      typedef typename Graph::Edge Edge;
   1.876    public:
   1.877 @@ -1544,7 +1605,8 @@
   1.878  	       const std::string& _id = std::string()) 
   1.879        : Parent(_reader), id(_id) {
   1.880        checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
   1.881 -      edgeIdReader.reset(new IdReader<Edge, _IdReader>(_idReader));
   1.882 +      edgeIdReader.reset(new _reader_bits::
   1.883 +			 IdReader<Edge, _IdReader>(_idReader));
   1.884      }
   1.885  
   1.886      /// \brief Destructor.
   1.887 @@ -1566,7 +1628,7 @@
   1.888  	msg << "Multiple read rule for edge: " << name;
   1.889  	throw IOParameterError(msg.message());
   1.890        }
   1.891 -      readers.insert(make_pair(name, &item));
   1.892 +      readers.insert(make_pair(name, _reader_bits::ItemStore<Edge>(item)));
   1.893      }
   1.894  
   1.895    protected:
   1.896 @@ -1598,18 +1660,27 @@
   1.897  	ls >> id;
   1.898  	typename EdgeReaders::iterator it = readers.find(id);
   1.899  	if (it != readers.end()) {
   1.900 -	  *(it->second) = edgeIdReader->read(ls); 
   1.901 +	  it->second.read(edgeIdReader->read(ls));
   1.902 +	  it->second.touch();
   1.903  	}	
   1.904        }
   1.905 +      for (typename EdgeReaders::iterator it = readers.begin();
   1.906 +	   it != readers.end(); ++it) {
   1.907 +	if (!it->second.touched()) {
   1.908 +	  ErrorMessage msg;
   1.909 +	  msg << "Edge not found in file: " << it->first;
   1.910 +	  throw IOParameterError(msg.message());
   1.911 +	}
   1.912 +      }
   1.913      }
   1.914      
   1.915    private:
   1.916  
   1.917      std::string id;
   1.918  
   1.919 -    typedef std::map<std::string, Edge*> EdgeReaders;
   1.920 +    typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
   1.921      EdgeReaders readers;
   1.922 -    std::auto_ptr<IdReaderBase<Edge> > edgeIdReader;
   1.923 +    std::auto_ptr<_reader_bits::IdReaderBase<Edge> > edgeIdReader;
   1.924    };
   1.925  
   1.926    /// \ingroup io_group
   1.927 @@ -1623,8 +1694,8 @@
   1.928    ///
   1.929    /// \relates LemonReader
   1.930    template <typename _Graph>
   1.931 -  class UndirEdgeReader : public CommonSectionReaderBase {
   1.932 -    typedef CommonSectionReaderBase Parent;
   1.933 +  class UndirEdgeReader : public LemonReader::SectionReader {
   1.934 +    typedef LemonReader::SectionReader Parent;
   1.935      typedef _Graph Graph;
   1.936      typedef typename Graph::Edge Edge;
   1.937      typedef typename Graph::UndirEdge UndirEdge;
   1.938 @@ -1643,8 +1714,10 @@
   1.939        : Parent(_reader), id(_id) {
   1.940        checkConcept<_reader_bits::ItemIdReader<UndirEdge>, _IdReader>();
   1.941        checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
   1.942 -      undirEdgeIdReader.reset(new IdReader<UndirEdge, _IdReader>(_idReader));
   1.943 -      edgeIdReader.reset(new IdReader<Edge, _IdReader>(_idReader));
   1.944 +      undirEdgeIdReader.reset(new _reader_bits::
   1.945 +			      IdReader<UndirEdge, _IdReader>(_idReader));
   1.946 +      edgeIdReader.reset(new _reader_bits::
   1.947 +			 IdReader<Edge, _IdReader>(_idReader));
   1.948      }
   1.949  
   1.950      /// \brief Destructor.
   1.951 @@ -1666,7 +1739,8 @@
   1.952  	msg << "Multiple read rule for undirected edge: " << name;
   1.953  	throw IOParameterError(msg.message());
   1.954        }
   1.955 -      undirEdgeReaders.insert(make_pair(name, &item));
   1.956 +      undirEdgeReaders.insert(make_pair(name, _reader_bits::
   1.957 +					ItemStore<UndirEdge>(item)));
   1.958      }
   1.959  
   1.960      /// \brief Add an edge reader command for the UndirEdgeReader.
   1.961 @@ -1678,7 +1752,7 @@
   1.962  	msg << "Multiple read rule for edge: " << name;
   1.963  	throw IOParameterError(msg.message());
   1.964        }
   1.965 -      edgeReaders.insert(make_pair(name, &item));
   1.966 +      edgeReaders.insert(make_pair(name, _reader_bits::ItemStore<Edge>(item)));
   1.967      }
   1.968  
   1.969    protected:
   1.970 @@ -1714,30 +1788,49 @@
   1.971  	{
   1.972  	  typename UndirEdgeReaders::iterator it = undirEdgeReaders.find(id);
   1.973  	  if (it != undirEdgeReaders.end()) {
   1.974 -	    *(it->second) = undirEdgeIdReader->read(ls); 
   1.975 -	    break;
   1.976 +	    it->second.read(undirEdgeIdReader->read(ls));
   1.977 +	    it->second.touch();
   1.978 +	    continue;
   1.979  	  }	
   1.980  	} {
   1.981  	  typename EdgeReaders::iterator it = edgeReaders.find(id);
   1.982  	  if (it != edgeReaders.end()) {
   1.983 -	    *(it->second) = edgeIdReader->read(ls); 
   1.984 -	    break;
   1.985 +	    it->second.read(edgeIdReader->read(ls));
   1.986 +	    it->second.touch();
   1.987 +	    continue;
   1.988  	  }	
   1.989  	}
   1.990        }
   1.991 +      for (typename EdgeReaders::iterator it = edgeReaders.begin();
   1.992 +	   it != edgeReaders.end(); ++it) {
   1.993 +	if (!it->second.touched()) {
   1.994 +	  ErrorMessage msg;
   1.995 +	  msg << "Edge not found in file: " << it->first;
   1.996 +	  throw IOParameterError(msg.message());
   1.997 +	}
   1.998 +      }
   1.999 +      for (typename UndirEdgeReaders::iterator it = undirEdgeReaders.begin();
  1.1000 +	   it != undirEdgeReaders.end(); ++it) {
  1.1001 +	if (!it->second.touched()) {
  1.1002 +	  ErrorMessage msg;
  1.1003 +	  msg << "UndirEdge not found in file: " << it->first;
  1.1004 +	  throw IOParameterError(msg.message());
  1.1005 +	}
  1.1006 +      }
  1.1007      }
  1.1008      
  1.1009    private:
  1.1010  
  1.1011      std::string id;
  1.1012  
  1.1013 -    typedef std::map<std::string, UndirEdge*> UndirEdgeReaders;
  1.1014 +    typedef std::map<std::string, 
  1.1015 +		     _reader_bits::ItemStore<UndirEdge> > UndirEdgeReaders;
  1.1016      UndirEdgeReaders undirEdgeReaders;
  1.1017 -    std::auto_ptr<IdReaderBase<UndirEdge> > undirEdgeIdReader;
  1.1018 +    std::auto_ptr<_reader_bits::IdReaderBase<UndirEdge> > undirEdgeIdReader;
  1.1019  
  1.1020 -    typedef std::map<std::string, Edge*> EdgeReaders;
  1.1021 +    typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  1.1022      EdgeReaders edgeReaders;
  1.1023 -    std::auto_ptr<IdReaderBase<Edge> > edgeIdReader;
  1.1024 +    std::auto_ptr<_reader_bits::IdReaderBase<Edge> > edgeIdReader;
  1.1025    };
  1.1026  
  1.1027    /// \ingroup io_group
  1.1028 @@ -1752,8 +1845,8 @@
  1.1029    ///
  1.1030    /// \relates LemonReader
  1.1031    template <typename _Traits = DefaultReaderTraits>
  1.1032 -  class AttributeReader : public CommonSectionReaderBase {
  1.1033 -    typedef CommonSectionReaderBase Parent;
  1.1034 +  class AttributeReader : public LemonReader::SectionReader {
  1.1035 +    typedef LemonReader::SectionReader Parent;
  1.1036      typedef _Traits Traits; 
  1.1037    public:
  1.1038      /// \brief Constructor.
  1.1039 @@ -1801,8 +1894,8 @@
  1.1040  	msg << "Multiple read rule for attribute: " << name;
  1.1041  	throw IOParameterError(msg.message());
  1.1042        }
  1.1043 -      readers.insert(make_pair(name, new ValueReader<Value, Reader>
  1.1044 -      			       (value, reader)));
  1.1045 +      readers.insert(make_pair(name, new _reader_bits::
  1.1046 +			       ValueReader<Value, Reader>(value, reader)));
  1.1047        return *this;
  1.1048      }
  1.1049  
  1.1050 @@ -1840,7 +1933,7 @@
  1.1051    private:
  1.1052      std::string id;
  1.1053  
  1.1054 -    typedef std::map<std::string, ValueReaderBase*> Readers;
  1.1055 +    typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers;
  1.1056      Readers readers;  
  1.1057    };
  1.1058