Implementation redesign
authordeba
Sat, 03 Dec 2005 18:17:29 +0000
changeset 1845f8bbfed86036
parent 1844 eaa5f5b855f7
child 1846 6b4e38acef1c
Implementation redesign
Throws exception
lemon/error.h
lemon/lemon_reader.h
lemon/lemon_writer.h
test/heap_test.cc
     1.1 --- a/lemon/error.h	Sat Dec 03 18:15:43 2005 +0000
     1.2 +++ b/lemon/error.h	Sat Dec 03 18:17:29 2005 +0000
     1.3 @@ -376,7 +376,7 @@
     1.4      virtual ~FileOpenError() throw() {}
     1.5    };
     1.6  
     1.7 -  class IOParameterError : public LogicError {
     1.8 +  class IOParameterError : public IOError {
     1.9    protected:
    1.10      ExceptionMember<std::string> _message;
    1.11      ExceptionMember<std::string> _file;
    1.12 @@ -385,7 +385,7 @@
    1.13    public:
    1.14  
    1.15      IOParameterError(const IOParameterError &ile) : 
    1.16 -      LogicError(ile), _message(ile._message), _file(ile._file) {}
    1.17 +      IOError(ile), _message(ile._message), _file(ile._file) {}
    1.18  
    1.19      ///\e 
    1.20      explicit IOParameterError(const char *the_message)
     2.1 --- a/lemon/lemon_reader.h	Sat Dec 03 18:15:43 2005 +0000
     2.2 +++ b/lemon/lemon_reader.h	Sat Dec 03 18:17:29 2005 +0000
     2.3 @@ -45,6 +45,18 @@
     2.4  
     2.5    namespace _reader_bits {
     2.6  
     2.7 +    template <typename T>
     2.8 +    bool operator<(T, T) {
     2.9 +      throw DataFormatError("Id is not comparable");
    2.10 +    }
    2.11 +
    2.12 +    template <typename T>
    2.13 +    struct Less {
    2.14 +      bool operator()(const T& p, const T& q) const {
    2.15 +	return p < q;
    2.16 +      }
    2.17 +    };
    2.18 +
    2.19      template <typename Item>
    2.20      class ItemIdReader {
    2.21      public:
    2.22 @@ -83,18 +95,6 @@
    2.23        };
    2.24  
    2.25      };
    2.26 -  
    2.27 -    template <typename T>
    2.28 -    bool operator<(T, T) {
    2.29 -      throw DataFormatError("Id is not comparable");
    2.30 -    }
    2.31 -
    2.32 -    template <typename T>
    2.33 -    struct Less {
    2.34 -      bool operator()(const T& p, const T& q) const {
    2.35 -	return p < q;
    2.36 -      }
    2.37 -    };
    2.38  
    2.39      template <typename Map>
    2.40      struct Ref { typedef Map& Type; };
    2.41 @@ -198,6 +198,253 @@
    2.42        typedef const YMap<Map>& Type;
    2.43      };
    2.44  
    2.45 +
    2.46 +    template <typename _Item>
    2.47 +    class MapReaderBase;
    2.48 +    
    2.49 +    template <typename _Item>
    2.50 +    class MapInverterBase : public MapReaderBase<_Item> {
    2.51 +    public:
    2.52 +      typedef _Item Item;
    2.53 +      virtual void read(std::istream&, const Item&) = 0;
    2.54 +      virtual Item read(std::istream&) const = 0;
    2.55 +
    2.56 +      virtual MapInverterBase<_Item>* getInverter() {
    2.57 +	return this;
    2.58 +      }
    2.59 +    };
    2.60 +
    2.61 +    template <typename _Item, typename _Map, typename _Reader>
    2.62 +    class MapReaderInverter : public MapInverterBase<_Item> {
    2.63 +    public:
    2.64 +      typedef _Item Item;
    2.65 +      typedef _Reader Reader;
    2.66 +      typedef typename Reader::Value Value;
    2.67 +      typedef _Map Map;
    2.68 +      typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
    2.69 +
    2.70 +      typename _reader_bits::Ref<Map>::Type map;
    2.71 +      Reader reader;
    2.72 +      Inverse inverse;
    2.73 +
    2.74 +      MapReaderInverter(typename _reader_bits::Arg<Map>::Type _map,
    2.75 +			const Reader& _reader) 
    2.76 +	: map(_map), reader(_reader) {}
    2.77 +
    2.78 +      virtual ~MapReaderInverter() {}
    2.79 +
    2.80 +      virtual void read(std::istream& is, const Item& item) {
    2.81 +	Value value;
    2.82 +	reader.read(is, value);
    2.83 +	map.set(item, value);
    2.84 +	typename Inverse::iterator it = inverse.find(value);
    2.85 +	if (it == inverse.end()) {
    2.86 +	  inverse.insert(std::make_pair(value, item));
    2.87 +	} else {
    2.88 +	  throw DataFormatError("Multiple ID occurence");
    2.89 +	}
    2.90 +      }
    2.91 +
    2.92 +      virtual Item read(std::istream& is) const {
    2.93 +	Value value;
    2.94 +	reader.read(is, value);	
    2.95 +	typename Inverse::const_iterator it = inverse.find(value);
    2.96 +	if (it != inverse.end()) {
    2.97 +	  return it->second;
    2.98 +	} else {
    2.99 +	  throw DataFormatError("Invalid ID error");
   2.100 +	}
   2.101 +      }      
   2.102 +    };
   2.103 +
   2.104 +    template <typename _Item, typename _Reader>
   2.105 +    class SkipReaderInverter : public MapInverterBase<_Item> {
   2.106 +    public:
   2.107 +      typedef _Item Item;
   2.108 +      typedef _Reader Reader;
   2.109 +      typedef typename Reader::Value Value;
   2.110 +      typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
   2.111 +
   2.112 +      Reader reader;
   2.113 +
   2.114 +      SkipReaderInverter(const Reader& _reader) 
   2.115 +	: reader(_reader) {}
   2.116 +
   2.117 +      virtual ~SkipReaderInverter() {}
   2.118 +
   2.119 +      virtual void read(std::istream& is, const Item& item) {
   2.120 +	Value value;
   2.121 +	reader.read(is, value);
   2.122 +	typename Inverse::iterator it = inverse.find(value);
   2.123 +	if (it == inverse.end()) {
   2.124 +	  inverse.insert(std::make_pair(value, item));
   2.125 +	} else {
   2.126 +	  throw DataFormatError("Multiple ID occurence error");
   2.127 +	}
   2.128 +      }
   2.129 +
   2.130 +      virtual Item read(std::istream& is) const {
   2.131 +	Value value;
   2.132 +	reader.read(is, value);	
   2.133 +	typename Inverse::const_iterator it = inverse.find(value);
   2.134 +	if (it != inverse.end()) {
   2.135 +	  return it->second;
   2.136 +	} else {
   2.137 +	  throw DataFormatError("Invalid ID error");
   2.138 +	}
   2.139 +      }
   2.140 +
   2.141 +    private:
   2.142 +      Inverse inverse;
   2.143 +    };
   2.144 +
   2.145 +    template <typename _Item>    
   2.146 +    class MapReaderBase {
   2.147 +    public:
   2.148 +      typedef _Item Item;
   2.149 +
   2.150 +      MapReaderBase() { _touched = false; }
   2.151 +      
   2.152 +      void touch() { _touched = true; }
   2.153 +      bool touched() const { return _touched; }
   2.154 +
   2.155 +      virtual ~MapReaderBase() {}
   2.156 +
   2.157 +      virtual void read(std::istream& is, const Item& item) = 0;
   2.158 +      virtual MapInverterBase<_Item>* getInverter() = 0;
   2.159 +
   2.160 +    private:      
   2.161 +      bool _touched;
   2.162 +
   2.163 +    };
   2.164 +
   2.165 +    template <typename _Item, typename _Map, typename _Reader>
   2.166 +    class MapReader : public MapReaderBase<_Item> {
   2.167 +    public:
   2.168 +      typedef _Map Map;
   2.169 +      typedef _Reader Reader;
   2.170 +      typedef typename Reader::Value Value;
   2.171 +      typedef _Item Item;
   2.172 +      
   2.173 +      typename _reader_bits::Ref<Map>::Type map;
   2.174 +      Reader reader;
   2.175 +
   2.176 +      MapReader(typename _reader_bits::Arg<Map>::Type _map, 
   2.177 +		const Reader& _reader) 
   2.178 +	: map(_map), reader(_reader) {}
   2.179 +
   2.180 +      virtual ~MapReader() {}
   2.181 +
   2.182 +      virtual void read(std::istream& is, const Item& item) {
   2.183 +	Value value;
   2.184 +	reader.read(is, value);
   2.185 +	map.set(item, value);
   2.186 +      }
   2.187 +
   2.188 +      virtual MapInverterBase<_Item>* getInverter() {
   2.189 +	return new MapReaderInverter<Item, Map, Reader>(map, reader);
   2.190 +      }
   2.191 +    };
   2.192 +
   2.193 +
   2.194 +    template <typename _Item, typename _Reader>
   2.195 +    class SkipReader : public MapReaderBase<_Item> {
   2.196 +    public:
   2.197 +      typedef _Reader Reader;
   2.198 +      typedef typename Reader::Value Value;
   2.199 +      typedef _Item Item;
   2.200 +
   2.201 +      Reader reader;
   2.202 +      SkipReader(const Reader& _reader) : reader(_reader) {}
   2.203 +
   2.204 +      virtual ~SkipReader() {}
   2.205 +
   2.206 +      virtual void read(std::istream& is, const Item&) {
   2.207 +	Value value;
   2.208 +	reader.read(is, value);
   2.209 +      }      
   2.210 +
   2.211 +      virtual MapInverterBase<Item>* getInverter() {
   2.212 +	return new SkipReaderInverter<Item, Reader>(reader);
   2.213 +      }
   2.214 +    };
   2.215 +
   2.216 +    template <typename _Item>
   2.217 +    class IdReaderBase {
   2.218 +    public:
   2.219 +      typedef _Item Item;
   2.220 +      virtual ~IdReaderBase() {}
   2.221 +      virtual Item read(std::istream& is) const = 0;
   2.222 +      virtual bool isIdReader() const = 0;
   2.223 +    };
   2.224 +
   2.225 +    template <typename _Item, typename _BoxedIdReader>
   2.226 +    class IdReader : public IdReaderBase<_Item> {
   2.227 +    public:
   2.228 +      typedef _Item Item;
   2.229 +      typedef _BoxedIdReader BoxedIdReader;
   2.230 +      
   2.231 +      const BoxedIdReader& boxedIdReader;
   2.232 +
   2.233 +      IdReader(const BoxedIdReader& _boxedIdReader) 
   2.234 +	: boxedIdReader(_boxedIdReader) {}
   2.235 +
   2.236 +      virtual Item read(std::istream& is) const {
   2.237 +	Item item;
   2.238 +	boxedIdReader.readId(is, item);
   2.239 +	return item;
   2.240 +      }
   2.241 +
   2.242 +      virtual bool isIdReader() const {
   2.243 +	return boxedIdReader.isIdReader();
   2.244 +      }
   2.245 +    };
   2.246 +
   2.247 +    template <typename _Item>
   2.248 +    class ItemStore {
   2.249 +    public:
   2.250 +
   2.251 +      typedef _Item Item;
   2.252 +
   2.253 +      ItemStore(Item& _item) : item(&_item) { 
   2.254 +	_touched = false; 
   2.255 +      }
   2.256 +      
   2.257 +      void touch() { _touched = true; }
   2.258 +      bool touched() const { return _touched; }
   2.259 +
   2.260 +      void read(const Item& _item) {
   2.261 +	*item = _item;
   2.262 +      }
   2.263 +      
   2.264 +    private:
   2.265 +      Item* item;
   2.266 +      bool _touched;
   2.267 +    };
   2.268 +
   2.269 +    class ValueReaderBase {
   2.270 +    public:
   2.271 +      virtual void read(std::istream&) {};
   2.272 +      virtual ~ValueReaderBase() {}
   2.273 +    };
   2.274 +
   2.275 +    template <typename _Value, typename _Reader>
   2.276 +    class ValueReader : public ValueReaderBase {
   2.277 +    public:
   2.278 +      typedef _Value Value;
   2.279 +      typedef _Reader Reader;
   2.280 +
   2.281 +      ValueReader(Value& _value, const Reader& _reader)
   2.282 + 	: value(_value), reader(_reader) {}
   2.283 +
   2.284 +      virtual void read(std::istream& is) {
   2.285 +	reader.read(is, value);
   2.286 +      }
   2.287 +    private:
   2.288 +      Value& value;
   2.289 +      Reader reader;
   2.290 +    };
   2.291 +
   2.292    }
   2.293  
   2.294    /// \ingroup io_group
   2.295 @@ -469,237 +716,6 @@
   2.296  
   2.297    };
   2.298  
   2.299 -  /// \brief Helper class for implementing the common SectionReaders.
   2.300 -  ///
   2.301 -  /// Helper class for implementing the common SectionReaders.
   2.302 -  class CommonSectionReaderBase : public LemonReader::SectionReader {
   2.303 -    typedef LemonReader::SectionReader Parent;
   2.304 -  protected:
   2.305 -    
   2.306 -    /// \brief Constructor for CommonSectionReaderBase.
   2.307 -    ///
   2.308 -    /// Constructor for CommonSectionReaderBase. It attach this reader to
   2.309 -    /// the given LemonReader.
   2.310 -    CommonSectionReaderBase(LemonReader& _reader) 
   2.311 -      : Parent(_reader) {}
   2.312 -
   2.313 -    template <typename _Item>
   2.314 -    class ReaderBase;
   2.315 -    
   2.316 -    template <typename _Item>
   2.317 -    class InverterBase : public ReaderBase<_Item> {
   2.318 -    public:
   2.319 -      typedef _Item Item;
   2.320 -      virtual void read(std::istream&, const Item&) = 0;
   2.321 -      virtual Item read(std::istream&) const = 0;
   2.322 -
   2.323 -      virtual InverterBase<_Item>* getInverter() {
   2.324 -	return this;
   2.325 -      }
   2.326 -    };
   2.327 -
   2.328 -    template <typename _Item, typename _Map, typename _Reader>
   2.329 -    class MapReaderInverter : public InverterBase<_Item> {
   2.330 -    public:
   2.331 -      typedef _Item Item;
   2.332 -      typedef _Reader Reader;
   2.333 -      typedef typename Reader::Value Value;
   2.334 -      typedef _Map Map;
   2.335 -      typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
   2.336 -
   2.337 -      typename _reader_bits::Ref<Map>::Type map;
   2.338 -      Reader reader;
   2.339 -      Inverse inverse;
   2.340 -
   2.341 -      MapReaderInverter(typename _reader_bits::Arg<Map>::Type _map,
   2.342 -			const Reader& _reader) 
   2.343 -	: map(_map), reader(_reader) {}
   2.344 -
   2.345 -      virtual ~MapReaderInverter() {}
   2.346 -
   2.347 -      virtual void read(std::istream& is, const Item& item) {
   2.348 -	Value value;
   2.349 -	reader.read(is, value);
   2.350 -	map.set(item, value);
   2.351 -	typename Inverse::iterator it = inverse.find(value);
   2.352 -	if (it == inverse.end()) {
   2.353 -	  inverse.insert(std::make_pair(value, item));
   2.354 -	} else {
   2.355 -	  throw DataFormatError("Multiple ID occurence");
   2.356 -	}
   2.357 -      }
   2.358 -
   2.359 -      virtual Item read(std::istream& is) const {
   2.360 -	Value value;
   2.361 -	reader.read(is, value);	
   2.362 -	typename Inverse::const_iterator it = inverse.find(value);
   2.363 -	if (it != inverse.end()) {
   2.364 -	  return it->second;
   2.365 -	} else {
   2.366 -	  throw DataFormatError("Invalid ID error");
   2.367 -	}
   2.368 -      }      
   2.369 -    };
   2.370 -
   2.371 -    template <typename _Item, typename _Reader>
   2.372 -    class SkipReaderInverter : public InverterBase<_Item> {
   2.373 -    public:
   2.374 -      typedef _Item Item;
   2.375 -      typedef _Reader Reader;
   2.376 -      typedef typename Reader::Value Value;
   2.377 -      typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
   2.378 -
   2.379 -      Reader reader;
   2.380 -
   2.381 -      SkipReaderInverter(const Reader& _reader) 
   2.382 -	: reader(_reader) {}
   2.383 -
   2.384 -      virtual ~SkipReaderInverter() {}
   2.385 -
   2.386 -      virtual void read(std::istream& is, const Item& item) {
   2.387 -	Value value;
   2.388 -	reader.read(is, value);
   2.389 -	typename Inverse::iterator it = inverse.find(value);
   2.390 -	if (it == inverse.end()) {
   2.391 -	  inverse.insert(std::make_pair(value, item));
   2.392 -	} else {
   2.393 -	  throw DataFormatError("Multiple ID occurence error");
   2.394 -	}
   2.395 -      }
   2.396 -
   2.397 -      virtual Item read(std::istream& is) const {
   2.398 -	Value value;
   2.399 -	reader.read(is, value);	
   2.400 -	typename Inverse::const_iterator it = inverse.find(value);
   2.401 -	if (it != inverse.end()) {
   2.402 -	  return it->second;
   2.403 -	} else {
   2.404 -	  throw DataFormatError("Invalid ID error");
   2.405 -	}
   2.406 -      }
   2.407 -
   2.408 -    private:
   2.409 -      Inverse inverse;
   2.410 -    };
   2.411 -
   2.412 -    template <typename _Item>    
   2.413 -    class ReaderBase {
   2.414 -    public:
   2.415 -      typedef _Item Item;
   2.416 -
   2.417 -      virtual ~ReaderBase() {}
   2.418 -
   2.419 -      virtual void read(std::istream& is, const Item& item) = 0;
   2.420 -      virtual InverterBase<_Item>* getInverter() = 0;
   2.421 -    };
   2.422 -
   2.423 -    template <typename _Item, typename _Map, typename _Reader>
   2.424 -    class MapReader : public ReaderBase<_Item> {
   2.425 -    public:
   2.426 -      typedef _Map Map;
   2.427 -      typedef _Reader Reader;
   2.428 -      typedef typename Reader::Value Value;
   2.429 -      typedef _Item Item;
   2.430 -      
   2.431 -      typename _reader_bits::Ref<Map>::Type map;
   2.432 -      Reader reader;
   2.433 -
   2.434 -      MapReader(typename _reader_bits::Arg<Map>::Type _map, 
   2.435 -		const Reader& _reader) 
   2.436 -	: map(_map), reader(_reader) {}
   2.437 -
   2.438 -      virtual ~MapReader() {}
   2.439 -
   2.440 -      virtual void read(std::istream& is, const Item& item) {
   2.441 -	Value value;
   2.442 -	reader.read(is, value);
   2.443 -	map.set(item, value);
   2.444 -      }
   2.445 -
   2.446 -      virtual InverterBase<_Item>* getInverter() {
   2.447 -	return new MapReaderInverter<Item, Map, Reader>(map, reader);
   2.448 -      }
   2.449 -    };
   2.450 -
   2.451 -
   2.452 -    template <typename _Item, typename _Reader>
   2.453 -    class SkipReader : public ReaderBase<_Item> {
   2.454 -    public:
   2.455 -      typedef _Reader Reader;
   2.456 -      typedef typename Reader::Value Value;
   2.457 -      typedef _Item Item;
   2.458 -
   2.459 -      Reader reader;
   2.460 -      SkipReader(const Reader& _reader) : reader(_reader) {}
   2.461 -
   2.462 -      virtual ~SkipReader() {}
   2.463 -
   2.464 -      virtual void read(std::istream& is, const Item&) {
   2.465 -	Value value;
   2.466 -	reader.read(is, value);
   2.467 -      }      
   2.468 -
   2.469 -      virtual InverterBase<Item>* getInverter() {
   2.470 -	return new SkipReaderInverter<Item, Reader>(reader);
   2.471 -      }
   2.472 -    };
   2.473 -
   2.474 -    template <typename _Item>
   2.475 -    class IdReaderBase {
   2.476 -    public:
   2.477 -      typedef _Item Item;
   2.478 -      virtual ~IdReaderBase() {}
   2.479 -      virtual Item read(std::istream& is) const = 0;
   2.480 -      virtual bool isIdReader() const = 0;
   2.481 -    };
   2.482 -
   2.483 -    template <typename _Item, typename _BoxedIdReader>
   2.484 -    class IdReader : public IdReaderBase<_Item> {
   2.485 -    public:
   2.486 -      typedef _Item Item;
   2.487 -      typedef _BoxedIdReader BoxedIdReader;
   2.488 -      
   2.489 -      const BoxedIdReader& boxedIdReader;
   2.490 -
   2.491 -      IdReader(const BoxedIdReader& _boxedIdReader) 
   2.492 -	: boxedIdReader(_boxedIdReader) {}
   2.493 -
   2.494 -      virtual Item read(std::istream& is) const {
   2.495 -	Item item;
   2.496 -	boxedIdReader.readId(is, item);
   2.497 -	return item;
   2.498 -      }
   2.499 -
   2.500 -      virtual bool isIdReader() const {
   2.501 -	return boxedIdReader.isIdReader();
   2.502 -      }
   2.503 -    };
   2.504 -
   2.505 -    class ValueReaderBase {
   2.506 -    public:
   2.507 -      virtual void read(std::istream&) {};
   2.508 -      virtual ~ValueReaderBase() {}
   2.509 -    };
   2.510 -
   2.511 -    template <typename _Value, typename _Reader>
   2.512 -    class ValueReader : public ValueReaderBase {
   2.513 -    public:
   2.514 -      typedef _Value Value;
   2.515 -      typedef _Reader Reader;
   2.516 -
   2.517 -      ValueReader(Value& _value, const Reader& _reader)
   2.518 - 	: value(_value), reader(_reader) {}
   2.519 -
   2.520 -      virtual void read(std::istream& is) {
   2.521 -	reader.read(is, value);
   2.522 -      }
   2.523 -    private:
   2.524 -      Value& value;
   2.525 -      Reader reader;
   2.526 -    };
   2.527 -    
   2.528 -  };
   2.529 -
   2.530    /// \ingroup io_group
   2.531    /// \brief SectionReader for reading a graph's nodeset.
   2.532    ///
   2.533 @@ -718,8 +734,8 @@
   2.534    ///
   2.535    /// \relates LemonReader
   2.536    template <typename _Graph, typename _Traits = DefaultReaderTraits>
   2.537 -  class NodeSetReader : public CommonSectionReaderBase {
   2.538 -    typedef CommonSectionReaderBase Parent;
   2.539 +  class NodeSetReader : public LemonReader::SectionReader {
   2.540 +    typedef LemonReader::SectionReader Parent;
   2.541    public:
   2.542  
   2.543      typedef _Graph Graph;
   2.544 @@ -801,9 +817,10 @@
   2.545  	ErrorMessage msg;
   2.546  	msg << "Multiple read rule for node map: " << name;
   2.547  	throw IOParameterError(msg.message());
   2.548 -      }
   2.549 +      }      
   2.550        readers.insert(
   2.551 -	make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
   2.552 +        make_pair(name, new _reader_bits::
   2.553 +		  MapReader<Node, Map, Reader>(map, reader)));
   2.554        return *this;
   2.555      }
   2.556  
   2.557 @@ -820,7 +837,8 @@
   2.558  	msg << "Multiple read rule for node map: " << name;
   2.559  	throw IOParameterError(msg.message());
   2.560        }
   2.561 -      readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
   2.562 +      readers.insert(make_pair(name, new _reader_bits::
   2.563 +			       SkipReader<Node, Reader>(reader)));
   2.564        return *this;
   2.565      }
   2.566  
   2.567 @@ -843,7 +861,7 @@
   2.568      ///
   2.569      /// It reads the content of the section.
   2.570      virtual void read(std::istream& is) {
   2.571 -      std::vector<ReaderBase<Node>* > index;
   2.572 +      std::vector<_reader_bits::MapReaderBase<Node>* > index;
   2.573        std::string line;
   2.574  
   2.575        getline(is, line);
   2.576 @@ -851,6 +869,7 @@
   2.577        while (ls >> id) {
   2.578  	typename MapReaders::iterator it = readers.find(id);
   2.579  	if (it != readers.end()) {
   2.580 +	  it->second->touch();
   2.581  	  index.push_back(it->second);
   2.582  	} else {
   2.583  	  index.push_back(&skipper);
   2.584 @@ -860,6 +879,14 @@
   2.585  	  index.back() = inverter.get();
   2.586  	}
   2.587        }
   2.588 +      for (typename MapReaders::iterator it = readers.begin();
   2.589 +	   it != readers.end(); ++it) {
   2.590 +	if (!it->second->touched()) {
   2.591 +	  ErrorMessage msg;
   2.592 +	  msg << "Map not found in file: " << it->first;
   2.593 +	  throw IOParameterError(msg.message());
   2.594 +	}
   2.595 +      }
   2.596        while (getline(is, line)) {	
   2.597  	Node node = graph.addNode();
   2.598  	std::istringstream ls(line);
   2.599 @@ -889,14 +916,14 @@
   2.600  
   2.601    private:
   2.602  
   2.603 -    typedef std::map<std::string, ReaderBase<Node>*> MapReaders;
   2.604 +    typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
   2.605      MapReaders readers;
   2.606     
   2.607      Graph& graph;   
   2.608      std::string id;
   2.609 -    SkipReader<Node, DefaultSkipper> skipper;
   2.610 +    _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
   2.611  
   2.612 -    std::auto_ptr<InverterBase<Node> > inverter;
   2.613 +    std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
   2.614    };
   2.615  
   2.616    /// \ingroup io_group
   2.617 @@ -922,8 +949,8 @@
   2.618    ///
   2.619    /// \relates LemonReader
   2.620    template <typename _Graph, typename _Traits = DefaultReaderTraits>
   2.621 -  class EdgeSetReader : public CommonSectionReaderBase {
   2.622 -    typedef CommonSectionReaderBase Parent;
   2.623 +  class EdgeSetReader : public LemonReader::SectionReader {
   2.624 +    typedef LemonReader::SectionReader Parent;
   2.625    public:
   2.626  
   2.627      typedef _Graph Graph;
   2.628 @@ -948,7 +975,8 @@
   2.629  		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   2.630        : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {
   2.631        checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>();
   2.632 -      nodeIdReader.reset(new IdReader<Node, NodeIdReader>(_nodeIdReader));
   2.633 +      nodeIdReader.reset(new _reader_bits::
   2.634 +			 IdReader<Node, NodeIdReader>(_nodeIdReader));
   2.635      }
   2.636      /// \brief Destructor.
   2.637      ///
   2.638 @@ -1013,7 +1041,8 @@
   2.639  	throw IOParameterError(msg.message());
   2.640        }
   2.641        readers.insert(
   2.642 -	make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   2.643 +	make_pair(name, new _reader_bits::
   2.644 +		  MapReader<Edge, Map, Reader>(map, reader)));
   2.645        return *this;
   2.646      }
   2.647  
   2.648 @@ -1030,7 +1059,8 @@
   2.649  	msg << "Multiple read rule for edge map: " << name;
   2.650  	throw IOParameterError(msg.message());
   2.651        }
   2.652 -      readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
   2.653 +      readers.insert(make_pair(name, new _reader_bits::
   2.654 +			       SkipReader<Edge, Reader>(reader)));
   2.655        return *this;
   2.656      }
   2.657  
   2.658 @@ -1056,7 +1086,7 @@
   2.659        if (!nodeIdReader->isIdReader()) {
   2.660  	throw DataFormatError("Cannot find nodeset or ID map");
   2.661        }
   2.662 -      std::vector<ReaderBase<Edge>* > index;
   2.663 +      std::vector<_reader_bits::MapReaderBase<Edge>* > index;
   2.664        std::string line;
   2.665  
   2.666        getline(is, line);
   2.667 @@ -1065,6 +1095,7 @@
   2.668  	typename MapReaders::iterator it = readers.find(id);
   2.669  	if (it != readers.end()) {
   2.670  	  index.push_back(it->second);
   2.671 +	  it->second->touch();
   2.672  	} else {
   2.673  	  index.push_back(&skipper);
   2.674  	}
   2.675 @@ -1073,6 +1104,14 @@
   2.676  	  index.back() = inverter.get();
   2.677  	}
   2.678        }
   2.679 +      for (typename MapReaders::iterator it = readers.begin();
   2.680 +	   it != readers.end(); ++it) {
   2.681 +	if (!it->second->touched()) {
   2.682 +	  ErrorMessage msg;
   2.683 +	  msg << "Map not found in file: " << it->first;
   2.684 +	  throw IOParameterError(msg.message());
   2.685 +	}
   2.686 +      }
   2.687        while (getline(is, line)) {	
   2.688  	std::istringstream ls(line);
   2.689  	Node from = nodeIdReader->read(ls);
   2.690 @@ -1104,15 +1143,15 @@
   2.691  
   2.692    private:
   2.693  
   2.694 -    typedef std::map<std::string, ReaderBase<Edge>*> MapReaders;
   2.695 +    typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
   2.696      MapReaders readers;
   2.697     
   2.698      Graph& graph;   
   2.699      std::string id;
   2.700 -    SkipReader<Edge, DefaultSkipper> skipper;
   2.701 +    _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
   2.702  
   2.703 -    std::auto_ptr<InverterBase<Edge> > inverter;
   2.704 -    std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
   2.705 +    std::auto_ptr<_reader_bits::MapInverterBase<Edge> > inverter;
   2.706 +    std::auto_ptr<_reader_bits::IdReaderBase<Node> > nodeIdReader;
   2.707    };
   2.708  
   2.709    /// \ingroup io_group
   2.710 @@ -1143,8 +1182,8 @@
   2.711    ///
   2.712    /// \relates LemonReader
   2.713    template <typename _Graph, typename _Traits = DefaultReaderTraits>
   2.714 -  class UndirEdgeSetReader : public CommonSectionReaderBase {
   2.715 -    typedef CommonSectionReaderBase Parent;
   2.716 +  class UndirEdgeSetReader : public LemonReader::SectionReader {
   2.717 +    typedef LemonReader::SectionReader Parent;
   2.718    public:
   2.719  
   2.720      typedef _Graph Graph;
   2.721 @@ -1170,7 +1209,8 @@
   2.722  		       const DefaultSkipper& _skipper = DefaultSkipper()) 
   2.723        : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {
   2.724        checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>();
   2.725 -      nodeIdReader.reset(new IdReader<Node, NodeIdReader>(_nodeIdReader));
   2.726 +      nodeIdReader.reset(new _reader_bits::
   2.727 +			 IdReader<Node, NodeIdReader>(_nodeIdReader));
   2.728      }
   2.729      /// \brief Destructor.
   2.730      ///
   2.731 @@ -1235,7 +1275,8 @@
   2.732  	throw IOParameterError(msg.message());
   2.733        }
   2.734        readers.insert(
   2.735 -	make_pair(name, new MapReader<UndirEdge, Map, Reader>(map, reader)));
   2.736 +	make_pair(name, new _reader_bits::
   2.737 +		  MapReader<UndirEdge, Map, Reader>(map, reader)));
   2.738        return *this;
   2.739      }
   2.740  
   2.741 @@ -1252,8 +1293,8 @@
   2.742  	msg << "Multiple read rule for node map: " << name;
   2.743  	throw IOParameterError(msg.message());
   2.744        }
   2.745 -      readers.insert(make_pair(name, 
   2.746 -			       new SkipReader<UndirEdge, Reader>(reader)));
   2.747 +      readers.insert(make_pair(name, new _reader_bits::
   2.748 +			       SkipReader<UndirEdge, Reader>(reader)));
   2.749        return *this;
   2.750      }
   2.751  
   2.752 @@ -1340,7 +1381,7 @@
   2.753        if (!nodeIdReader->isIdReader()) {
   2.754  	throw DataFormatError("Cannot find nodeset or ID map");
   2.755        }
   2.756 -      std::vector<ReaderBase<UndirEdge>* > index;
   2.757 +      std::vector<_reader_bits::MapReaderBase<UndirEdge>* > index;
   2.758        std::string line;
   2.759  
   2.760        getline(is, line);
   2.761 @@ -1349,6 +1390,7 @@
   2.762  	typename MapReaders::iterator it = readers.find(id);
   2.763  	if (it != readers.end()) {
   2.764  	  index.push_back(it->second);
   2.765 +	  it->second->touch();
   2.766  	} else {
   2.767  	  index.push_back(&skipper);
   2.768  	}
   2.769 @@ -1357,6 +1399,14 @@
   2.770  	  index.back() = inverter.get();
   2.771  	}
   2.772        }
   2.773 +      for (typename MapReaders::iterator it = readers.begin();
   2.774 +	   it != readers.end(); ++it) {
   2.775 +	if (!it->second->touched()) {
   2.776 +	  ErrorMessage msg;
   2.777 +	  msg << "Map not found in file: " << it->first;
   2.778 +	  throw IOParameterError(msg.message());
   2.779 +	}
   2.780 +      }
   2.781        while (getline(is, line)) {	
   2.782  	std::istringstream ls(line);
   2.783  	Node from = nodeIdReader->read(ls);
   2.784 @@ -1408,15 +1458,16 @@
   2.785  
   2.786    private:
   2.787  
   2.788 -    typedef std::map<std::string, ReaderBase<UndirEdge>*> MapReaders;
   2.789 +    typedef std::map<std::string, 
   2.790 +		     _reader_bits::MapReaderBase<UndirEdge>*> MapReaders;
   2.791      MapReaders readers;
   2.792     
   2.793      Graph& graph;   
   2.794      std::string id;
   2.795 -    SkipReader<UndirEdge, DefaultSkipper> skipper;
   2.796 +    _reader_bits::SkipReader<UndirEdge, DefaultSkipper> skipper;
   2.797  
   2.798 -    std::auto_ptr<InverterBase<UndirEdge> > inverter;
   2.799 -    std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
   2.800 +    std::auto_ptr<_reader_bits::MapInverterBase<UndirEdge> > inverter;
   2.801 +    std::auto_ptr<_reader_bits::IdReaderBase<Node> > nodeIdReader;
   2.802    };
   2.803  
   2.804    /// \ingroup io_group
   2.805 @@ -1430,8 +1481,8 @@
   2.806    ///
   2.807    /// \relates LemonReader
   2.808    template <typename _Graph>
   2.809 -  class NodeReader : public CommonSectionReaderBase {
   2.810 -    typedef CommonSectionReaderBase Parent;
   2.811 +  class NodeReader : public LemonReader::SectionReader {
   2.812 +    typedef LemonReader::SectionReader Parent;
   2.813      typedef _Graph Graph;
   2.814      typedef typename Graph::Node Node;
   2.815    public:
   2.816 @@ -1447,7 +1498,8 @@
   2.817  	       const std::string& _id = std::string()) 
   2.818        : Parent(_reader), id(_id) {
   2.819        checkConcept<_reader_bits::ItemIdReader<Node>, _IdReader>();
   2.820 -      nodeIdReader.reset(new IdReader<Node, _IdReader>(_idReader));
   2.821 +      nodeIdReader.reset(new _reader_bits::
   2.822 +			 IdReader<Node, _IdReader>(_idReader));
   2.823      }
   2.824  
   2.825      /// \brief Destructor.
   2.826 @@ -1470,7 +1522,7 @@
   2.827  	msg << "Multiple read rule for node: " << name;
   2.828  	throw IOParameterError(msg.message());
   2.829        }
   2.830 -      readers.insert(make_pair(name, &item));
   2.831 +      readers.insert(make_pair(name, _reader_bits::ItemStore<Node>(item)));
   2.832      }
   2.833  
   2.834    protected:
   2.835 @@ -1502,18 +1554,27 @@
   2.836  	ls >> id;
   2.837  	typename NodeReaders::iterator it = readers.find(id);
   2.838  	if (it != readers.end()) {
   2.839 -	  *(it->second) = nodeIdReader->read(ls); 
   2.840 +	  it->second.read(nodeIdReader->read(ls));
   2.841 +	  it->second.touch();
   2.842  	}	
   2.843        }
   2.844 +      for (typename NodeReaders::iterator it = readers.begin();
   2.845 +	   it != readers.end(); ++it) {
   2.846 +	if (!it->second.touched()) {
   2.847 +	  ErrorMessage msg;
   2.848 +	  msg << "Node not found in file: " << it->first;
   2.849 +	  throw IOParameterError(msg.message());
   2.850 +	}
   2.851 +      }
   2.852      }
   2.853      
   2.854    private:
   2.855  
   2.856      std::string id;
   2.857  
   2.858 -    typedef std::map<std::string, Node*> NodeReaders;
   2.859 +    typedef std::map<std::string, _reader_bits::ItemStore<Node> > NodeReaders;
   2.860      NodeReaders readers;
   2.861 -    std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
   2.862 +    std::auto_ptr<_reader_bits::IdReaderBase<Node> > nodeIdReader;
   2.863    };
   2.864  
   2.865    /// \ingroup io_group
   2.866 @@ -1527,8 +1588,8 @@
   2.867    ///
   2.868    /// \relates LemonReader
   2.869    template <typename _Graph>
   2.870 -  class EdgeReader : public CommonSectionReaderBase {
   2.871 -    typedef CommonSectionReaderBase Parent;
   2.872 +  class EdgeReader : public LemonReader::SectionReader {
   2.873 +    typedef LemonReader::SectionReader Parent;
   2.874      typedef _Graph Graph;
   2.875      typedef typename Graph::Edge Edge;
   2.876    public:
   2.877 @@ -1544,7 +1605,8 @@
   2.878  	       const std::string& _id = std::string()) 
   2.879        : Parent(_reader), id(_id) {
   2.880        checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
   2.881 -      edgeIdReader.reset(new IdReader<Edge, _IdReader>(_idReader));
   2.882 +      edgeIdReader.reset(new _reader_bits::
   2.883 +			 IdReader<Edge, _IdReader>(_idReader));
   2.884      }
   2.885  
   2.886      /// \brief Destructor.
   2.887 @@ -1566,7 +1628,7 @@
   2.888  	msg << "Multiple read rule for edge: " << name;
   2.889  	throw IOParameterError(msg.message());
   2.890        }
   2.891 -      readers.insert(make_pair(name, &item));
   2.892 +      readers.insert(make_pair(name, _reader_bits::ItemStore<Edge>(item)));
   2.893      }
   2.894  
   2.895    protected:
   2.896 @@ -1598,18 +1660,27 @@
   2.897  	ls >> id;
   2.898  	typename EdgeReaders::iterator it = readers.find(id);
   2.899  	if (it != readers.end()) {
   2.900 -	  *(it->second) = edgeIdReader->read(ls); 
   2.901 +	  it->second.read(edgeIdReader->read(ls));
   2.902 +	  it->second.touch();
   2.903  	}	
   2.904        }
   2.905 +      for (typename EdgeReaders::iterator it = readers.begin();
   2.906 +	   it != readers.end(); ++it) {
   2.907 +	if (!it->second.touched()) {
   2.908 +	  ErrorMessage msg;
   2.909 +	  msg << "Edge not found in file: " << it->first;
   2.910 +	  throw IOParameterError(msg.message());
   2.911 +	}
   2.912 +      }
   2.913      }
   2.914      
   2.915    private:
   2.916  
   2.917      std::string id;
   2.918  
   2.919 -    typedef std::map<std::string, Edge*> EdgeReaders;
   2.920 +    typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
   2.921      EdgeReaders readers;
   2.922 -    std::auto_ptr<IdReaderBase<Edge> > edgeIdReader;
   2.923 +    std::auto_ptr<_reader_bits::IdReaderBase<Edge> > edgeIdReader;
   2.924    };
   2.925  
   2.926    /// \ingroup io_group
   2.927 @@ -1623,8 +1694,8 @@
   2.928    ///
   2.929    /// \relates LemonReader
   2.930    template <typename _Graph>
   2.931 -  class UndirEdgeReader : public CommonSectionReaderBase {
   2.932 -    typedef CommonSectionReaderBase Parent;
   2.933 +  class UndirEdgeReader : public LemonReader::SectionReader {
   2.934 +    typedef LemonReader::SectionReader Parent;
   2.935      typedef _Graph Graph;
   2.936      typedef typename Graph::Edge Edge;
   2.937      typedef typename Graph::UndirEdge UndirEdge;
   2.938 @@ -1643,8 +1714,10 @@
   2.939        : Parent(_reader), id(_id) {
   2.940        checkConcept<_reader_bits::ItemIdReader<UndirEdge>, _IdReader>();
   2.941        checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
   2.942 -      undirEdgeIdReader.reset(new IdReader<UndirEdge, _IdReader>(_idReader));
   2.943 -      edgeIdReader.reset(new IdReader<Edge, _IdReader>(_idReader));
   2.944 +      undirEdgeIdReader.reset(new _reader_bits::
   2.945 +			      IdReader<UndirEdge, _IdReader>(_idReader));
   2.946 +      edgeIdReader.reset(new _reader_bits::
   2.947 +			 IdReader<Edge, _IdReader>(_idReader));
   2.948      }
   2.949  
   2.950      /// \brief Destructor.
   2.951 @@ -1666,7 +1739,8 @@
   2.952  	msg << "Multiple read rule for undirected edge: " << name;
   2.953  	throw IOParameterError(msg.message());
   2.954        }
   2.955 -      undirEdgeReaders.insert(make_pair(name, &item));
   2.956 +      undirEdgeReaders.insert(make_pair(name, _reader_bits::
   2.957 +					ItemStore<UndirEdge>(item)));
   2.958      }
   2.959  
   2.960      /// \brief Add an edge reader command for the UndirEdgeReader.
   2.961 @@ -1678,7 +1752,7 @@
   2.962  	msg << "Multiple read rule for edge: " << name;
   2.963  	throw IOParameterError(msg.message());
   2.964        }
   2.965 -      edgeReaders.insert(make_pair(name, &item));
   2.966 +      edgeReaders.insert(make_pair(name, _reader_bits::ItemStore<Edge>(item)));
   2.967      }
   2.968  
   2.969    protected:
   2.970 @@ -1714,30 +1788,49 @@
   2.971  	{
   2.972  	  typename UndirEdgeReaders::iterator it = undirEdgeReaders.find(id);
   2.973  	  if (it != undirEdgeReaders.end()) {
   2.974 -	    *(it->second) = undirEdgeIdReader->read(ls); 
   2.975 -	    break;
   2.976 +	    it->second.read(undirEdgeIdReader->read(ls));
   2.977 +	    it->second.touch();
   2.978 +	    continue;
   2.979  	  }	
   2.980  	} {
   2.981  	  typename EdgeReaders::iterator it = edgeReaders.find(id);
   2.982  	  if (it != edgeReaders.end()) {
   2.983 -	    *(it->second) = edgeIdReader->read(ls); 
   2.984 -	    break;
   2.985 +	    it->second.read(edgeIdReader->read(ls));
   2.986 +	    it->second.touch();
   2.987 +	    continue;
   2.988  	  }	
   2.989  	}
   2.990        }
   2.991 +      for (typename EdgeReaders::iterator it = edgeReaders.begin();
   2.992 +	   it != edgeReaders.end(); ++it) {
   2.993 +	if (!it->second.touched()) {
   2.994 +	  ErrorMessage msg;
   2.995 +	  msg << "Edge not found in file: " << it->first;
   2.996 +	  throw IOParameterError(msg.message());
   2.997 +	}
   2.998 +      }
   2.999 +      for (typename UndirEdgeReaders::iterator it = undirEdgeReaders.begin();
  2.1000 +	   it != undirEdgeReaders.end(); ++it) {
  2.1001 +	if (!it->second.touched()) {
  2.1002 +	  ErrorMessage msg;
  2.1003 +	  msg << "UndirEdge not found in file: " << it->first;
  2.1004 +	  throw IOParameterError(msg.message());
  2.1005 +	}
  2.1006 +      }
  2.1007      }
  2.1008      
  2.1009    private:
  2.1010  
  2.1011      std::string id;
  2.1012  
  2.1013 -    typedef std::map<std::string, UndirEdge*> UndirEdgeReaders;
  2.1014 +    typedef std::map<std::string, 
  2.1015 +		     _reader_bits::ItemStore<UndirEdge> > UndirEdgeReaders;
  2.1016      UndirEdgeReaders undirEdgeReaders;
  2.1017 -    std::auto_ptr<IdReaderBase<UndirEdge> > undirEdgeIdReader;
  2.1018 +    std::auto_ptr<_reader_bits::IdReaderBase<UndirEdge> > undirEdgeIdReader;
  2.1019  
  2.1020 -    typedef std::map<std::string, Edge*> EdgeReaders;
  2.1021 +    typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  2.1022      EdgeReaders edgeReaders;
  2.1023 -    std::auto_ptr<IdReaderBase<Edge> > edgeIdReader;
  2.1024 +    std::auto_ptr<_reader_bits::IdReaderBase<Edge> > edgeIdReader;
  2.1025    };
  2.1026  
  2.1027    /// \ingroup io_group
  2.1028 @@ -1752,8 +1845,8 @@
  2.1029    ///
  2.1030    /// \relates LemonReader
  2.1031    template <typename _Traits = DefaultReaderTraits>
  2.1032 -  class AttributeReader : public CommonSectionReaderBase {
  2.1033 -    typedef CommonSectionReaderBase Parent;
  2.1034 +  class AttributeReader : public LemonReader::SectionReader {
  2.1035 +    typedef LemonReader::SectionReader Parent;
  2.1036      typedef _Traits Traits; 
  2.1037    public:
  2.1038      /// \brief Constructor.
  2.1039 @@ -1801,8 +1894,8 @@
  2.1040  	msg << "Multiple read rule for attribute: " << name;
  2.1041  	throw IOParameterError(msg.message());
  2.1042        }
  2.1043 -      readers.insert(make_pair(name, new ValueReader<Value, Reader>
  2.1044 -      			       (value, reader)));
  2.1045 +      readers.insert(make_pair(name, new _reader_bits::
  2.1046 +			       ValueReader<Value, Reader>(value, reader)));
  2.1047        return *this;
  2.1048      }
  2.1049  
  2.1050 @@ -1840,7 +1933,7 @@
  2.1051    private:
  2.1052      std::string id;
  2.1053  
  2.1054 -    typedef std::map<std::string, ValueReaderBase*> Readers;
  2.1055 +    typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers;
  2.1056      Readers readers;  
  2.1057    };
  2.1058  
     3.1 --- a/lemon/lemon_writer.h	Sat Dec 03 18:15:43 2005 +0000
     3.2 +++ b/lemon/lemon_writer.h	Sat Dec 03 18:17:29 2005 +0000
     3.3 @@ -164,6 +164,95 @@
     3.4        typedef ConstYMap<Map> Type;
     3.5      };
     3.6  
     3.7 +
     3.8 +    template <typename _Item>    
     3.9 +    class MapWriterBase {
    3.10 +    public:
    3.11 +      typedef _Item Item;
    3.12 +
    3.13 +      virtual ~MapWriterBase() {}
    3.14 +
    3.15 +      virtual void write(std::ostream& os, const Item& item) = 0;
    3.16 +    };
    3.17 +
    3.18 +
    3.19 +    template <typename _Item, typename _Map, typename _Writer>
    3.20 +    class MapWriter : public MapWriterBase<_Item> {
    3.21 +    public:
    3.22 +      typedef _Map Map;
    3.23 +      typedef _Writer Writer;
    3.24 +      typedef typename Writer::Value Value;
    3.25 +      typedef _Item Item;
    3.26 +      
    3.27 +      typename _writer_bits::Ref<Map>::Type map;
    3.28 +      Writer writer;
    3.29 +
    3.30 +      MapWriter(const Map& _map, const Writer& _writer) 
    3.31 +	: map(_map), writer(_writer) {}
    3.32 +
    3.33 +      virtual ~MapWriter() {}
    3.34 +
    3.35 +      virtual void write(std::ostream& os, const Item& item) {
    3.36 +	Value value = map[item];
    3.37 +	writer.write(os, value);
    3.38 +      }
    3.39 +
    3.40 +    };
    3.41 +
    3.42 +
    3.43 +    class ValueWriterBase {
    3.44 +    public:
    3.45 +      virtual ~ValueWriterBase() {}
    3.46 +      virtual void write(std::ostream&) = 0;
    3.47 +    };
    3.48 +
    3.49 +    template <typename _Value, typename _Writer>
    3.50 +    class ValueWriter : public ValueWriterBase {
    3.51 +    public:
    3.52 +      typedef _Value Value;
    3.53 +      typedef _Writer Writer;
    3.54 +
    3.55 +      ValueWriter(const Value& _value, const Writer& _writer)
    3.56 + 	: value(_value), writer(_writer) {}
    3.57 +
    3.58 +      virtual void write(std::ostream& os) {
    3.59 +	writer.write(os, value);
    3.60 +      }
    3.61 +    private:
    3.62 +      const Value& value;
    3.63 +      Writer writer;
    3.64 +    };
    3.65 +    
    3.66 +
    3.67 +    template <typename _Item>
    3.68 +    class IdWriterBase {
    3.69 +    public:
    3.70 +      typedef _Item Item;
    3.71 +      virtual ~IdWriterBase() {}
    3.72 +      virtual void write(std::ostream&, const Item&) const = 0;
    3.73 +      virtual bool isIdWriter() const = 0;
    3.74 +    };
    3.75 +
    3.76 +    template <typename _Item, typename _BoxedIdWriter>
    3.77 +    class IdWriter : public IdWriterBase<_Item> {
    3.78 +    public:
    3.79 +      typedef _Item Item;
    3.80 +      typedef _BoxedIdWriter BoxedIdWriter;
    3.81 +
    3.82 +      const BoxedIdWriter& idWriter;
    3.83 +
    3.84 +      IdWriter(const BoxedIdWriter& _idWriter) 
    3.85 +	: idWriter(_idWriter) {}
    3.86 +
    3.87 +      virtual void write(std::ostream& os, const Item& item) const {
    3.88 +	idWriter.writeId(os, item);
    3.89 +      }
    3.90 +
    3.91 +      virtual bool isIdWriter() const {
    3.92 +	return idWriter.isIdWriter();
    3.93 +      }
    3.94 +    };
    3.95 +
    3.96    }
    3.97  
    3.98    /// \ingroup io_group
    3.99 @@ -281,109 +370,6 @@
   3.100  
   3.101    };
   3.102  
   3.103 -  /// \brief Helper class for implementing the common SectionWriters.
   3.104 -  ///
   3.105 -  /// Helper class for implementing the common SectionWriters.
   3.106 -  class CommonSectionWriterBase : public LemonWriter::SectionWriter {
   3.107 -    typedef LemonWriter::SectionWriter Parent;
   3.108 -  protected:
   3.109 -    
   3.110 -    /// \brief Constructor for CommonSectionWriterBase.
   3.111 -    ///
   3.112 -    /// Constructor for CommonSectionWriterBase. It attach this writer to
   3.113 -    /// the given LemonWriter.
   3.114 -    CommonSectionWriterBase(LemonWriter& _writer) 
   3.115 -      : Parent(_writer) {}
   3.116 -
   3.117 -    template <typename _Item>    
   3.118 -    class WriterBase {
   3.119 -    public:
   3.120 -      typedef _Item Item;
   3.121 -
   3.122 -      virtual ~WriterBase() {}
   3.123 -
   3.124 -      virtual void write(std::ostream& os, const Item& item) = 0;
   3.125 -    };
   3.126 -
   3.127 -
   3.128 -    template <typename _Item, typename _Map, typename _Writer>
   3.129 -    class MapWriter : public WriterBase<_Item> {
   3.130 -    public:
   3.131 -      typedef _Map Map;
   3.132 -      typedef _Writer Writer;
   3.133 -      typedef typename Writer::Value Value;
   3.134 -      typedef _Item Item;
   3.135 -      
   3.136 -      typename _writer_bits::Ref<Map>::Type map;
   3.137 -      Writer writer;
   3.138 -
   3.139 -      MapWriter(const Map& _map, const Writer& _writer) 
   3.140 -	: map(_map), writer(_writer) {}
   3.141 -
   3.142 -      virtual ~MapWriter() {}
   3.143 -
   3.144 -      virtual void write(std::ostream& os, const Item& item) {
   3.145 -	Value value = map[item];
   3.146 -	writer.write(os, value);
   3.147 -      }
   3.148 -
   3.149 -    };
   3.150 -
   3.151 -
   3.152 -    class ValueWriterBase {
   3.153 -    public:
   3.154 -      virtual ~ValueWriterBase() {}
   3.155 -      virtual void write(std::ostream&) = 0;
   3.156 -    };
   3.157 -
   3.158 -    template <typename _Value, typename _Writer>
   3.159 -    class ValueWriter : public ValueWriterBase {
   3.160 -    public:
   3.161 -      typedef _Value Value;
   3.162 -      typedef _Writer Writer;
   3.163 -
   3.164 -      ValueWriter(const Value& _value, const Writer& _writer)
   3.165 - 	: value(_value), writer(_writer) {}
   3.166 -
   3.167 -      virtual void write(std::ostream& os) {
   3.168 -	writer.write(os, value);
   3.169 -      }
   3.170 -    private:
   3.171 -      const Value& value;
   3.172 -      Writer writer;
   3.173 -    };
   3.174 -    
   3.175 -
   3.176 -    template <typename _Item>
   3.177 -    class IdWriterBase {
   3.178 -    public:
   3.179 -      typedef _Item Item;
   3.180 -      virtual ~IdWriterBase() {}
   3.181 -      virtual void write(std::ostream&, const Item&) const = 0;
   3.182 -      virtual bool isIdWriter() const = 0;
   3.183 -    };
   3.184 -
   3.185 -    template <typename _Item, typename _BoxedIdWriter>
   3.186 -    class IdWriter : public IdWriterBase<_Item> {
   3.187 -    public:
   3.188 -      typedef _Item Item;
   3.189 -      typedef _BoxedIdWriter BoxedIdWriter;
   3.190 -
   3.191 -      const BoxedIdWriter& idWriter;
   3.192 -
   3.193 -      IdWriter(const BoxedIdWriter& _idWriter) 
   3.194 -	: idWriter(_idWriter) {}
   3.195 -
   3.196 -      virtual void write(std::ostream& os, const Item& item) const {
   3.197 -	idWriter.writeId(os, item);
   3.198 -      }
   3.199 -
   3.200 -      virtual bool isIdWriter() const {
   3.201 -	return idWriter.isIdWriter();
   3.202 -      }
   3.203 -    };
   3.204 -  };
   3.205 -
   3.206    /// \ingroup io_group
   3.207    /// \brief SectionWriter for writing a graph's nodeset.
   3.208    ///
   3.209 @@ -403,8 +389,8 @@
   3.210    ///
   3.211    /// \relates LemonWriter
   3.212    template <typename _Graph, typename _Traits = DefaultWriterTraits>
   3.213 -  class NodeSetWriter : public CommonSectionWriterBase {
   3.214 -    typedef CommonSectionWriterBase Parent;
   3.215 +  class NodeSetWriter : public LemonWriter::SectionWriter {
   3.216 +    typedef LemonWriter::SectionWriter Parent;
   3.217    public:
   3.218  
   3.219      typedef _Graph Graph;
   3.220 @@ -457,7 +443,8 @@
   3.221        checkConcept<concept::ReadMap<Node, typename Map::Value>, Map>();
   3.222        checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
   3.223        writers.push_back(
   3.224 -	make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
   3.225 +	make_pair(name, new _writer_bits::
   3.226 +		  MapWriter<Node, Map, Writer>(map, writer)));
   3.227        return *this;
   3.228      }
   3.229  
   3.230 @@ -527,10 +514,11 @@
   3.231  
   3.232    private:
   3.233  
   3.234 -    typedef std::vector<std::pair<std::string, WriterBase<Node>*> > MapWriters;
   3.235 +    typedef std::vector<std::pair<std::string, _writer_bits::
   3.236 +				  MapWriterBase<Node>*> > MapWriters;
   3.237      MapWriters writers;
   3.238  
   3.239 -    WriterBase<Node>* idMap;
   3.240 +    _writer_bits::MapWriterBase<Node>* idMap;
   3.241      bool forceIdMap;
   3.242     
   3.243      const Graph& graph;   
   3.244 @@ -562,8 +550,8 @@
   3.245    ///
   3.246    /// \relates LemonWriter
   3.247    template <typename _Graph, typename _Traits = DefaultWriterTraits>
   3.248 -  class EdgeSetWriter : public CommonSectionWriterBase {
   3.249 -    typedef CommonSectionWriterBase Parent;
   3.250 +  class EdgeSetWriter : public LemonWriter::SectionWriter {
   3.251 +    typedef LemonWriter::SectionWriter Parent;
   3.252    public:
   3.253  
   3.254      typedef _Graph Graph;
   3.255 @@ -586,7 +574,8 @@
   3.256        : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
   3.257  	graph(_graph), id(_id) {
   3.258        checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>();
   3.259 -      nodeIdWriter.reset(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
   3.260 +      nodeIdWriter.reset(new _writer_bits::
   3.261 +			 IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
   3.262      } 
   3.263  
   3.264      /// \brief Destructor.
   3.265 @@ -623,7 +612,8 @@
   3.266        checkConcept<concept::ReadMap<Edge, typename Map::Value>, Map>();
   3.267        checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
   3.268        writers.push_back(
   3.269 -	make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
   3.270 +	make_pair(name, new _writer_bits::
   3.271 +		  MapWriter<Edge, Map, Writer>(map, writer)));
   3.272        return *this;
   3.273      }
   3.274  
   3.275 @@ -701,16 +691,17 @@
   3.276  
   3.277    private:
   3.278  
   3.279 -    typedef std::vector<std::pair<std::string, WriterBase<Edge>*> > MapWriters;
   3.280 +    typedef std::vector<std::pair<std::string, _writer_bits::
   3.281 +				  MapWriterBase<Edge>*> > MapWriters;
   3.282      MapWriters writers;
   3.283  
   3.284 -    WriterBase<Edge>* idMap;
   3.285 +    _writer_bits::MapWriterBase<Edge>* idMap;
   3.286      bool forceIdMap;
   3.287     
   3.288      const Graph& graph;   
   3.289      std::string id;
   3.290  
   3.291 -    std::auto_ptr<IdWriterBase<Node> > nodeIdWriter;
   3.292 +    std::auto_ptr<_writer_bits::IdWriterBase<Node> > nodeIdWriter;
   3.293    };
   3.294  
   3.295    /// \ingroup io_group
   3.296 @@ -743,8 +734,8 @@
   3.297    ///
   3.298    /// \relates LemonWriter
   3.299    template <typename _Graph, typename _Traits = DefaultWriterTraits>
   3.300 -  class UndirEdgeSetWriter : public CommonSectionWriterBase {
   3.301 -    typedef CommonSectionWriterBase Parent;
   3.302 +  class UndirEdgeSetWriter : public LemonWriter::SectionWriter {
   3.303 +    typedef LemonWriter::SectionWriter Parent;
   3.304    public:
   3.305  
   3.306      typedef _Graph Graph;
   3.307 @@ -768,7 +759,8 @@
   3.308        : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
   3.309  	graph(_graph), id(_id) {
   3.310        checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>();
   3.311 -      nodeIdWriter.reset(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
   3.312 +      nodeIdWriter.reset(new _writer_bits::
   3.313 +			 IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
   3.314      } 
   3.315  
   3.316      /// \brief Destructor.
   3.317 @@ -805,7 +797,8 @@
   3.318        checkConcept<concept::ReadMap<UndirEdge, typename Map::Value>, Map>();
   3.319        checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
   3.320        writers.push_back(
   3.321 -	make_pair(name, new MapWriter<UndirEdge, Map, Writer>(map, writer)));
   3.322 +	make_pair(name, new _writer_bits::
   3.323 +		  MapWriter<UndirEdge, Map, Writer>(map, writer)));
   3.324        return *this;
   3.325      }
   3.326  
   3.327 @@ -928,17 +921,17 @@
   3.328  
   3.329    private:
   3.330  
   3.331 -    typedef std::vector<std::pair<std::string, 
   3.332 -				  WriterBase<UndirEdge>*> > MapWriters;
   3.333 +    typedef std::vector<std::pair<std::string, _writer_bits::
   3.334 +				  MapWriterBase<UndirEdge>*> > MapWriters;
   3.335      MapWriters writers;
   3.336  
   3.337 -    WriterBase<UndirEdge>* idMap;
   3.338 +    _writer_bits::MapWriterBase<UndirEdge>* idMap;
   3.339      bool forceIdMap;
   3.340     
   3.341      const Graph& graph;   
   3.342      std::string id;
   3.343  
   3.344 -    std::auto_ptr<IdWriterBase<Node> > nodeIdWriter;
   3.345 +    std::auto_ptr<_writer_bits::IdWriterBase<Node> > nodeIdWriter;
   3.346    };
   3.347  
   3.348    /// \ingroup io_group
   3.349 @@ -952,8 +945,8 @@
   3.350    ///
   3.351    /// \relates LemonWriter
   3.352    template <typename _Graph>
   3.353 -  class NodeWriter : public CommonSectionWriterBase {
   3.354 -    typedef CommonSectionWriterBase Parent;
   3.355 +  class NodeWriter : public LemonWriter::SectionWriter {
   3.356 +    typedef LemonWriter::SectionWriter Parent;
   3.357      typedef _Graph Graph;
   3.358      typedef typename Graph::Node Node;
   3.359    public:
   3.360 @@ -968,7 +961,7 @@
   3.361  	       const std::string& _id = std::string()) 
   3.362        : Parent(_writer), id(_id) {
   3.363        checkConcept<_writer_bits::ItemIdWriter<Node>, _IdWriter>();
   3.364 -      idWriter.reset(new IdWriter<Node, _IdWriter>(_idWriter));
   3.365 +      idWriter.reset(new _writer_bits::IdWriter<Node, _IdWriter>(_idWriter));
   3.366      }
   3.367  
   3.368  
   3.369 @@ -1020,7 +1013,7 @@
   3.370  
   3.371      typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
   3.372      NodeWriters writers;
   3.373 -    std::auto_ptr<IdWriterBase<Node> > idWriter;
   3.374 +    std::auto_ptr<_writer_bits::IdWriterBase<Node> > idWriter;
   3.375    };
   3.376  
   3.377    /// \ingroup io_group
   3.378 @@ -1034,8 +1027,8 @@
   3.379    ///
   3.380    /// \relates LemonWriter
   3.381    template <typename _Graph>
   3.382 -  class EdgeWriter : public CommonSectionWriterBase {
   3.383 -    typedef CommonSectionWriterBase Parent;
   3.384 +  class EdgeWriter : public LemonWriter::SectionWriter {
   3.385 +    typedef LemonWriter::SectionWriter Parent;
   3.386      typedef _Graph Graph;
   3.387      typedef typename Graph::Edge Edge;
   3.388    public:
   3.389 @@ -1050,7 +1043,7 @@
   3.390  	       const std::string& _id = std::string()) 
   3.391        : Parent(_writer), id(_id) {
   3.392        checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>();
   3.393 -      idWriter.reset(new IdWriter<Edge, _IdWriter>(_idWriter));
   3.394 +      idWriter.reset(new _writer_bits::IdWriter<Edge, _IdWriter>(_idWriter));
   3.395      }
   3.396  
   3.397      /// \brief Destructor.
   3.398 @@ -1101,7 +1094,7 @@
   3.399      typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
   3.400      EdgeWriters writers;
   3.401  
   3.402 -    std::auto_ptr<IdWriterBase<Edge> > idWriter;
   3.403 +    std::auto_ptr<_writer_bits::IdWriterBase<Edge> > idWriter;
   3.404    };
   3.405  
   3.406    /// \ingroup io_group
   3.407 @@ -1115,8 +1108,8 @@
   3.408    ///
   3.409    /// \relates LemonWriter
   3.410    template <typename _Graph>
   3.411 -  class UndirEdgeWriter : public CommonSectionWriterBase {
   3.412 -    typedef CommonSectionWriterBase Parent;
   3.413 +  class UndirEdgeWriter : public LemonWriter::SectionWriter {
   3.414 +    typedef LemonWriter::SectionWriter Parent;
   3.415      typedef _Graph Graph;
   3.416      typedef typename Graph::Node Node;
   3.417      typedef typename Graph::Edge Edge;
   3.418 @@ -1135,8 +1128,10 @@
   3.419        : Parent(_writer), id(_id) {
   3.420        checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>();
   3.421        checkConcept<_writer_bits::ItemIdWriter<UndirEdge>, _IdWriter>();
   3.422 -      undirEdgeIdWriter.reset(new IdWriter<UndirEdge, _IdWriter>(_idWriter));
   3.423 -      edgeIdWriter.reset(new IdWriter<Edge, _IdWriter>(_idWriter));
   3.424 +      undirEdgeIdWriter.reset(new _writer_bits::
   3.425 +			      IdWriter<UndirEdge, _IdWriter>(_idWriter));
   3.426 +      edgeIdWriter.reset(new _writer_bits::
   3.427 +			 IdWriter<Edge, _IdWriter>(_idWriter));
   3.428      }
   3.429  
   3.430      /// \brief Destructor.
   3.431 @@ -1202,11 +1197,11 @@
   3.432      typedef std::vector<std::pair<std::string, 
   3.433  				  const UndirEdge*> > UndirEdgeWriters;
   3.434      UndirEdgeWriters undirEdgeWriters;
   3.435 -    std::auto_ptr<IdWriterBase<UndirEdge> > undirEdgeIdWriter;
   3.436 +    std::auto_ptr<_writer_bits::IdWriterBase<UndirEdge> > undirEdgeIdWriter;
   3.437  
   3.438      typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
   3.439      EdgeWriters edgeWriters;
   3.440 -    std::auto_ptr<IdWriterBase<Edge> > edgeIdWriter;
   3.441 +    std::auto_ptr<_writer_bits::IdWriterBase<Edge> > edgeIdWriter;
   3.442  
   3.443    };
   3.444  
   3.445 @@ -1222,8 +1217,8 @@
   3.446    ///
   3.447    /// \relates LemonWriter
   3.448    template <typename _Traits = DefaultWriterTraits>
   3.449 -  class AttributeWriter : public CommonSectionWriterBase {
   3.450 -    typedef CommonSectionWriterBase Parent;
   3.451 +  class AttributeWriter : public LemonWriter::SectionWriter {
   3.452 +    typedef LemonWriter::SectionWriter Parent;
   3.453      typedef _Traits Traits; 
   3.454    public:
   3.455      /// \brief Constructor.
   3.456 @@ -1267,8 +1262,8 @@
   3.457  				    const Value& value,
   3.458  				    const Writer& writer = Writer()) {
   3.459        checkConcept<_writer_bits::ItemWriter<Value>, Writer>();
   3.460 -      writers.push_back(make_pair(name, new ValueWriter<Value, Writer>
   3.461 -      			       (value, writer)));
   3.462 +      writers.push_back(make_pair(name, new _writer_bits::
   3.463 +				  ValueWriter<Value, Writer>(value, writer)));
   3.464        return *this;
   3.465      }
   3.466  
   3.467 @@ -1296,7 +1291,8 @@
   3.468    private:
   3.469      std::string id;
   3.470  
   3.471 -    typedef std::vector<std::pair<std::string, ValueWriterBase*> > Writers;
   3.472 +    typedef std::vector<std::pair<std::string, 
   3.473 +				  _writer_bits::ValueWriterBase*> > Writers;
   3.474      Writers writers;  
   3.475    };
   3.476  
     4.1 --- a/test/heap_test.cc	Sat Dec 03 18:15:43 2005 +0000
     4.2 +++ b/test/heap_test.cc	Sat Dec 03 18:17:29 2005 +0000
     4.3 @@ -56,7 +56,7 @@
     4.4    std::ifstream input(f_name.c_str());
     4.5    check(input, "Input file '" << f_name << "' not found.");
     4.6    GraphReader<Graph>(input, graph).
     4.7 -    readEdgeMap("length", length).
     4.8 +    readEdgeMap("capacity", length).
     4.9      readNode("source", start).
    4.10      run();  
    4.11