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