lemon_reader.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  *
00003  * This file is a part of LEMON, a generic C++ optimization library
00004  *
00005  * Copyright (C) 2003-2006
00006  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00007  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00008  *
00009  * Permission to use, modify and distribute this software is granted
00010  * provided that this copyright notice appears in all copies. For
00011  * precise terms see the accompanying LICENSE file.
00012  *
00013  * This software is provided "AS IS" with no warranty of any kind,
00014  * express or implied, and with no claim as to its suitability for any
00015  * purpose.
00016  *
00017  */
00018 
00022 
00023 
00024 #ifndef LEMON_LEMON_READER_H
00025 #define LEMON_LEMON_READER_H
00026 
00027 
00028 #include <iostream>
00029 #include <fstream>
00030 #include <string>
00031 #include <vector>
00032 #include <algorithm>
00033 #include <map>
00034 #include <memory>
00035 
00036 #include <lemon/error.h>
00037 #include <lemon/graph_utils.h>
00038 #include <lemon/utility.h>
00039 #include <lemon/bits/item_reader.h>
00040 
00041 #include <lemon/xy.h>
00042 
00043 #include <lemon/concept_check.h>
00044 #include <lemon/concept/maps.h>
00045 
00046 namespace lemon {
00047 
00048   namespace _reader_bits {
00049 
00050     template <typename T>
00051     bool operator<(T, T) {
00052       throw DataFormatError("Label is not comparable");
00053     }
00054 
00055     template <typename T>
00056     struct Less {
00057       bool operator()(const T& p, const T& q) const {
00058         return p < q;
00059       }
00060     };
00061 
00062     template <typename Item>
00063     class ItemLabelReader {
00064     public:
00065 
00066       bool isLabelReader() { return true; }
00067 
00068       void readLabel(std::istream&, Item&) {}
00069       
00070       template <class _ItemLabelReader>
00071       struct Constraints {
00072         void constraints() {
00073           bool b = reader.isLabelReader();
00074           ignore_unused_variable_warning(b);
00075           Item item;
00076           reader.readLabel(is, item);
00077         }
00078         _ItemLabelReader& reader;
00079         std::istream& is;
00080       };
00081 
00082     };
00083 
00084     template <typename Item>
00085     class ItemReader {
00086     public:
00087       void read(std::istream&, Item&) {}
00088       
00089       template <class _ItemReader>
00090       struct Constraints {
00091         void constraints() {
00092           Item item;
00093           reader.read(is, item);
00094         }
00095         _ItemReader& reader;
00096         std::istream& is;
00097       };
00098 
00099     };
00100 
00101     template <typename Map>
00102     struct Ref { typedef Map& Type; };
00103     template <typename Map>
00104     struct Arg { typedef Map& Type; };
00105 
00106     template <typename Graph, typename Map>
00107     class ForwardComposeMap {
00108     public:
00109       typedef typename Graph::UEdge Key;
00110       typedef typename Map::Value Value;
00111 
00112       ForwardComposeMap(const Graph& _graph, typename Arg<Map>::Type _map) 
00113         : graph(_graph), map(_map) {}
00114       
00115       void set(const Key& key, const Value& val) {
00116         map.set(graph.direct(key, true), val);
00117       }
00118 
00119     private:
00120       typename Ref<Map>::Type map;
00121       const Graph& graph;
00122     };
00123 
00124     template <typename Graph, typename Map>
00125     ForwardComposeMap<Graph, Map>
00126     forwardComposeMap(const Graph& graph, const Map& map) {
00127       return ForwardComposeMap<Graph, Map>(graph, map);
00128     }
00129 
00130     template <typename Graph, typename Map>
00131     ForwardComposeMap<Graph, Map>
00132     forwardComposeMap(const Graph& graph, Map& map) {
00133       return ForwardComposeMap<Graph, Map>(graph, map);
00134     }
00135 
00136     template <typename Graph, typename Map>
00137     class BackwardComposeMap {
00138     public:
00139       typedef typename Graph::UEdge Key;
00140       typedef typename Map::Value Value;
00141 
00142       BackwardComposeMap(const Graph& _graph, typename Arg<Map>::Type _map) 
00143         : graph(_graph), map(_map) {}
00144       
00145       void set(const Key& key, const Value& val) {
00146         map.set(graph.direct(key, false), val);
00147       }
00148 
00149     private:
00150       typename Ref<Map>::Type map;
00151       const Graph& graph;
00152     };
00153 
00154 
00155     template <typename Graph, typename Map>
00156     BackwardComposeMap<Graph, Map>
00157     backwardComposeMap(const Graph& graph, const Map& map) {
00158       return BackwardComposeMap<Graph, Map>(graph, map);
00159     }
00160 
00161     template <typename Graph, typename Map>
00162     BackwardComposeMap<Graph, Map>
00163     backwardComposeMap(const Graph& graph, Map& map) {
00164       return BackwardComposeMap<Graph, Map>(graph, map);
00165     }
00166 
00167     template <typename Graph, typename Map>
00168     struct Ref<ForwardComposeMap<Graph, Map> > { 
00169       typedef ForwardComposeMap<Graph, Map> Type;
00170     };
00171     template <typename Graph, typename Map>
00172     struct Arg<ForwardComposeMap<Graph, Map> > { 
00173       typedef const ForwardComposeMap<Graph, Map>& Type;
00174     };
00175 
00176     template <typename Graph, typename Map>
00177     struct Ref<BackwardComposeMap<Graph, Map> > { 
00178       typedef BackwardComposeMap<Graph, Map> Type; 
00179     };
00180     template <typename Graph, typename Map>
00181     struct Arg<BackwardComposeMap<Graph, Map> > { 
00182       typedef const BackwardComposeMap<Graph, Map>& Type; 
00183     };
00184 
00185     template <typename Map>
00186     struct Ref<XMap<Map> > { 
00187       typedef XMap<Map> Type;
00188     };
00189     template <typename Map>
00190     struct Arg<XMap<Map> > { 
00191       typedef const XMap<Map>& Type;
00192     };
00193 
00194     template <typename Map>
00195     struct Ref<YMap<Map> > { 
00196       typedef YMap<Map> Type;
00197     };
00198     template <typename Map>
00199     struct Arg<YMap<Map> > { 
00200       typedef const YMap<Map>& Type;
00201     };
00202 
00203 
00204     template <typename _Item>
00205     class MapReaderBase;
00206     
00207     template <typename _Item>
00208     class MapInverterBase : public MapReaderBase<_Item> {
00209     public:
00210       typedef _Item Item;
00211       virtual void read(std::istream&, const Item&) = 0;
00212       virtual Item read(std::istream&) const = 0;
00213 
00214       virtual MapInverterBase<_Item>* getInverter() {
00215         return this;
00216       }
00217     };
00218 
00219     template <typename _Item, typename _Map, typename _Reader>
00220     class MapReaderInverter : public MapInverterBase<_Item> {
00221     public:
00222       typedef _Item Item;
00223       typedef _Reader Reader;
00224       typedef typename Reader::Value Value;
00225       typedef _Map Map;
00226       typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
00227 
00228       typename _reader_bits::Ref<Map>::Type map;
00229       Reader reader;
00230       Inverse inverse;
00231 
00232       MapReaderInverter(typename _reader_bits::Arg<Map>::Type _map,
00233                         const Reader& _reader) 
00234         : map(_map), reader(_reader) {}
00235 
00236       virtual ~MapReaderInverter() {}
00237 
00238       virtual void read(std::istream& is, const Item& item) {
00239         Value value;
00240         reader.read(is, value);
00241         map.set(item, value);
00242         typename Inverse::iterator it = inverse.find(value);
00243         if (it == inverse.end()) {
00244           inverse.insert(std::make_pair(value, item));
00245         } else {
00246           throw DataFormatError("Multiple label occurence");
00247         }
00248       }
00249 
00250       virtual Item read(std::istream& is) const {
00251         Value value;
00252         reader.read(is, value); 
00253         typename Inverse::const_iterator it = inverse.find(value);
00254         if (it != inverse.end()) {
00255           return it->second;
00256         } else {
00257           throw DataFormatError("Invalid label error");
00258         }
00259       }      
00260     };
00261 
00262     template <typename _Item, typename _Reader>
00263     class SkipReaderInverter : public MapInverterBase<_Item> {
00264     public:
00265       typedef _Item Item;
00266       typedef _Reader Reader;
00267       typedef typename Reader::Value Value;
00268       typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
00269 
00270       Reader reader;
00271 
00272       SkipReaderInverter(const Reader& _reader) 
00273         : reader(_reader) {}
00274 
00275       virtual ~SkipReaderInverter() {}
00276 
00277       virtual void read(std::istream& is, const Item& item) {
00278         Value value;
00279         reader.read(is, value);
00280         typename Inverse::iterator it = inverse.find(value);
00281         if (it == inverse.end()) {
00282           inverse.insert(std::make_pair(value, item));
00283         } else {
00284           throw DataFormatError("Multiple label occurence error");
00285         }
00286       }
00287 
00288       virtual Item read(std::istream& is) const {
00289         Value value;
00290         reader.read(is, value); 
00291         typename Inverse::const_iterator it = inverse.find(value);
00292         if (it != inverse.end()) {
00293           return it->second;
00294         } else {
00295           throw DataFormatError("Invalid label error");
00296         }
00297       }
00298 
00299     private:
00300       Inverse inverse;
00301     };
00302 
00303     template <typename _Item>    
00304     class MapReaderBase {
00305     public:
00306       typedef _Item Item;
00307 
00308       MapReaderBase() { _touched = false; }
00309       
00310       void touch() { _touched = true; }
00311       bool touched() const { return _touched; }
00312 
00313       virtual ~MapReaderBase() {}
00314 
00315       virtual void read(std::istream& is, const Item& item) = 0;
00316       virtual MapInverterBase<_Item>* getInverter() = 0;
00317 
00318     private:      
00319       bool _touched;
00320 
00321     };
00322 
00323     template <typename _Item, typename _Map, typename _Reader>
00324     class MapReader : public MapReaderBase<_Item> {
00325     public:
00326       typedef _Map Map;
00327       typedef _Reader Reader;
00328       typedef typename Reader::Value Value;
00329       typedef _Item Item;
00330       
00331       typename _reader_bits::Ref<Map>::Type map;
00332       Reader reader;
00333 
00334       MapReader(typename _reader_bits::Arg<Map>::Type _map, 
00335                 const Reader& _reader) 
00336         : map(_map), reader(_reader) {}
00337 
00338       virtual ~MapReader() {}
00339 
00340       virtual void read(std::istream& is, const Item& item) {
00341         Value value;
00342         reader.read(is, value);
00343         map.set(item, value);
00344       }
00345 
00346       virtual MapInverterBase<_Item>* getInverter() {
00347         return new MapReaderInverter<Item, Map, Reader>(map, reader);
00348       }
00349     };
00350 
00351 
00352     template <typename _Item, typename _Reader>
00353     class SkipReader : public MapReaderBase<_Item> {
00354     public:
00355       typedef _Reader Reader;
00356       typedef typename Reader::Value Value;
00357       typedef _Item Item;
00358 
00359       Reader reader;
00360       SkipReader(const Reader& _reader) : reader(_reader) {}
00361 
00362       virtual ~SkipReader() {}
00363 
00364       virtual void read(std::istream& is, const Item&) {
00365         Value value;
00366         reader.read(is, value);
00367       }      
00368 
00369       virtual MapInverterBase<Item>* getInverter() {
00370         return new SkipReaderInverter<Item, Reader>(reader);
00371       }
00372     };
00373 
00374     template <typename _Item>
00375     class LabelReaderBase {
00376     public:
00377       typedef _Item Item;
00378       virtual ~LabelReaderBase() {}
00379       virtual Item read(std::istream& is) const = 0;
00380       virtual bool isLabelReader() const = 0;
00381     };
00382 
00383     template <typename _Item, typename _BoxedLabelReader>
00384     class LabelReader : public LabelReaderBase<_Item> {
00385     public:
00386       typedef _Item Item;
00387       typedef _BoxedLabelReader BoxedLabelReader;
00388       
00389       const BoxedLabelReader& boxedLabelReader;
00390 
00391       LabelReader(const BoxedLabelReader& _boxedLabelReader) 
00392         : boxedLabelReader(_boxedLabelReader) {}
00393 
00394       virtual Item read(std::istream& is) const {
00395         Item item;
00396         boxedLabelReader.readLabel(is, item);
00397         return item;
00398       }
00399 
00400       virtual bool isLabelReader() const {
00401         return boxedLabelReader.isLabelReader();
00402       }
00403     };
00404 
00405     template <typename _Item>
00406     class ItemStore {
00407     public:
00408 
00409       typedef _Item Item;
00410 
00411       ItemStore(Item& _item) : item(&_item) { 
00412         _touched = false; 
00413       }
00414       
00415       void touch() { _touched = true; }
00416       bool touched() const { return _touched; }
00417 
00418       void read(const Item& _item) {
00419         *item = _item;
00420       }
00421       
00422     private:
00423       Item* item;
00424       bool _touched;
00425     };
00426 
00427     class ValueReaderBase {
00428     public:
00429       virtual void read(std::istream&) {};
00430       ValueReaderBase() { _touched = false; }
00431 
00432       void touch() { _touched = true; }
00433       bool touched() const { return _touched; }
00434 
00435       virtual ~ValueReaderBase() {}
00436     private:
00437       bool _touched;
00438     };
00439 
00440     template <typename _Value, typename _Reader>
00441     class ValueReader : public ValueReaderBase {
00442     public:
00443       typedef _Value Value;
00444       typedef _Reader Reader;
00445 
00446       ValueReader(Value& _value, const Reader& _reader)
00447         : value(_value), reader(_reader) {}
00448 
00449       virtual void read(std::istream& is) {
00450         reader.read(is, value);
00451       }
00452     private:
00453       Value& value;
00454       Reader reader;
00455     };
00456 
00457   }
00458 
00489   class LemonReader {
00490   private:
00491     
00492     class FilterStreamBuf : public std::streambuf {
00493     public:
00494 
00495       typedef std::streambuf Parent;
00496       typedef Parent::char_type char_type;
00497       FilterStreamBuf(std::istream& is, int& num) 
00498         : _is(is), _base(0), _eptr(0), 
00499           _num(num), skip_state(after_endl) {}
00500 
00501     protected:
00502 
00503       enum skip_state_type {
00504         no_skip,
00505         after_endl,
00506         comment_line
00507       };
00508 
00509       char_type small_buf[1];
00510 
00511 
00512       std::istream& _is;
00513 
00514       char_type* _base;
00515       char_type* _eptr;
00516 
00517       int& _num;
00518 
00519       skip_state_type skip_state;
00520 
00521 
00522       char_type* base() { return _base; }
00523 
00524       char_type* eptr() { return _eptr; }
00525 
00526       int blen() { return _eptr - _base; }
00527 
00528       void setb(char_type* buf, int len) {
00529         _base = buf;
00530         _eptr = buf + len;
00531       }
00532   
00533       virtual std::streambuf* setbuf(char *buf, std::streamsize len) {
00534         if (base()) return 0;
00535         if (buf != 0 && len >= (int)sizeof(small_buf)) {
00536           setb(buf, len);
00537         } else {
00538           setb(small_buf, sizeof(small_buf));
00539         }
00540         setg(0, 0, 0);
00541         return this;
00542       }
00543 
00544       bool put_char(char c) {
00545         switch (skip_state) {
00546         case no_skip:
00547           switch (c) {
00548           case '\n': 
00549             skip_state = after_endl;
00550             return true;
00551           default:
00552             return true;
00553           }
00554         case after_endl:
00555           switch (c) {
00556           case '@':
00557             return false;
00558           case '\n': 
00559             return false;
00560           case '#':
00561             skip_state = comment_line;
00562             return false;
00563           default:
00564             if (!isspace(c)) {
00565               skip_state = no_skip;
00566               return true;
00567             } else {
00568               return false;
00569             }
00570           }
00571           break;
00572         case comment_line:
00573           switch (c) {
00574           case '\n': 
00575             skip_state = after_endl;
00576             return false;
00577           default:
00578             return false;
00579           }
00580         }
00581         return false;
00582       }
00583 
00584       virtual int underflow() {
00585         char c;
00586         if (_is.read(&c, 1)) {
00587           _is.putback(c);
00588           if (c == '@') {
00589             return EOF;
00590           }
00591         } else {
00592           return EOF;
00593         }
00594         char_type *ptr;
00595         for (ptr = base(); ptr != eptr(); ++ptr) {
00596           if (_is.read(&c, 1)) {
00597             if (c == '\n') ++_num;
00598             if (put_char(c)) {
00599               *ptr = c;
00600             } else {
00601               if (skip_state == after_endl && c == '@') {
00602                 _is.putback('@');
00603                 break;
00604               }
00605               --ptr;
00606             }
00607           } else {
00608             break;
00609           }
00610         }
00611         setg(base(), base(), ptr);
00612         return *base();
00613       }
00614 
00615       virtual int sync() {
00616         return EOF;
00617       }
00618     };
00619 
00620   public:
00621 
00630     class SectionReader {
00631       friend class LemonReader;
00632     protected:
00637       SectionReader(LemonReader& reader) {
00638         reader.attach(*this);
00639       }
00640 
00641       virtual ~SectionReader() {}
00642 
00648       virtual bool header(const std::string& line) = 0;
00649 
00653       virtual void read(std::istream& is) = 0;
00654     };
00655 
00659     LemonReader(std::istream& _is) 
00660       : is(&_is), own_is(false) {}
00661 
00665     LemonReader(const std::string& filename) 
00666       : is(0), own_is(true) {
00667       is = new std::ifstream(filename.c_str());
00668       if (is->fail()) {
00669         throw FileOpenError(filename);
00670       }
00671     }
00672 
00676     ~LemonReader() {
00677       if (own_is) {
00678         delete is;
00679       }
00680     }
00681 
00682   private:
00683     LemonReader(const LemonReader&);
00684     void operator=(const LemonReader&);
00685 
00686     void attach(SectionReader& reader) {
00687       readers.push_back(&reader);
00688     }
00689 
00690   public:
00694     void run() {
00695       int line_num = 0;
00696       std::string line;
00697       try {
00698         while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
00699           SectionReaders::iterator it;
00700           for (it = readers.begin(); it != readers.end(); ++it) {
00701             if ((*it)->header(line)) {
00702               char buf[2048];
00703               FilterStreamBuf buffer(*is, line_num);
00704               buffer.pubsetbuf(buf, sizeof(buf));
00705               std::istream is(&buffer);
00706               (*it)->read(is);
00707               break;
00708             }
00709           }
00710         }
00711       } catch (DataFormatError& error) {
00712         error.line(line_num);
00713         throw error;
00714       } 
00715     }
00716 
00717 
00718   private:
00719 
00720     std::istream* is;
00721     bool own_is;
00722 
00723     typedef std::vector<SectionReader*> SectionReaders;
00724     SectionReaders readers;
00725 
00726   };
00727 
00745   template <typename _Graph, typename _Traits = DefaultReaderTraits>
00746   class NodeSetReader : public LemonReader::SectionReader {
00747     typedef LemonReader::SectionReader Parent;
00748   public:
00749 
00750     typedef _Graph Graph;
00751     typedef _Traits Traits;
00752     typedef typename Graph::Node Node;
00753     typedef typename Traits::Skipper DefaultSkipper;
00754 
00761     NodeSetReader(LemonReader& _reader, 
00762                   Graph& _graph, 
00763                   const std::string& _name = std::string(),
00764                   const DefaultSkipper& _skipper = DefaultSkipper()) 
00765       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {} 
00766 
00767 
00771     virtual ~NodeSetReader() {
00772       for (typename MapReaders::iterator it = readers.begin(); 
00773            it != readers.end(); ++it) {
00774         delete it->second;
00775       }
00776     }
00777 
00778   private:
00779     NodeSetReader(const NodeSetReader&);
00780     void operator=(const NodeSetReader&);
00781   
00782   public:
00783 
00787     template <typename Map>
00788     NodeSetReader& readNodeMap(std::string name, Map& map) {
00789       return _readMap<
00790         typename Traits::template Reader<typename Map::Value>, Map,
00791         typename _reader_bits::Arg<Map>::Type>(name, map);
00792     }
00793 
00794     template <typename Map>
00795     NodeSetReader& readNodeMap(std::string name, const Map& map) {
00796       return _readMap<
00797         typename Traits::template Reader<typename Map::Value>, Map,
00798         typename _reader_bits::Arg<Map>::Type>(name, map);
00799     }
00800 
00804     template <typename Reader, typename Map>
00805     NodeSetReader& readNodeMap(std::string name, Map& map, 
00806                                const Reader& reader = Reader()) {
00807       return _readMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
00808         (name, map, reader);
00809     }
00810 
00811     template <typename Reader, typename Map>
00812     NodeSetReader& readNodeMap(std::string name, const Map& map, 
00813                                const Reader& reader = Reader()) {
00814       return _readMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
00815         (name, map, reader);
00816     }
00817 
00818   private:
00819 
00820     template <typename Reader, typename Map, typename MapParameter>
00821     NodeSetReader& _readMap(std::string name, MapParameter map, 
00822                             const Reader& reader = Reader()) {
00823       checkConcept<concept::WriteMap<Node, typename Map::Value>, Map>();
00824       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
00825       if (readers.find(name) != readers.end()) {
00826         ErrorMessage msg;
00827         msg << "Multiple read rule for node map: " << name;
00828         throw IOParameterError(msg.message());
00829       }      
00830       readers.insert(
00831         make_pair(name, new _reader_bits::
00832                   MapReader<Node, Map, Reader>(map, reader)));
00833       return *this;
00834     }
00835 
00836   public:
00837 
00841     template <typename Reader>
00842     NodeSetReader& skipNodeMap(std::string name, 
00843                            const Reader& reader = Reader()) {
00844       if (readers.find(name) != readers.end()) {
00845         ErrorMessage msg;
00846         msg << "Multiple read rule for node map: " << name;
00847         throw IOParameterError(msg.message());
00848       }
00849       readers.insert(make_pair(name, new _reader_bits::
00850                                SkipReader<Node, Reader>(reader)));
00851       return *this;
00852     }
00853 
00854   protected:
00855 
00861     virtual bool header(const std::string& line) {
00862       std::istringstream ls(line);
00863       std::string command;
00864       std::string id;
00865       ls >> command >> name;
00866       return command == "@nodeset" && name == id;
00867     }
00868 
00872     virtual void read(std::istream& is) {
00873       std::vector<_reader_bits::MapReaderBase<Node>* > index;
00874       std::string line;
00875 
00876       getline(is, line);
00877       std::istringstream ls(line);
00878       std::string id;
00879       while (ls >> id) {
00880         typename MapReaders::iterator it = readers.find(id);
00881         if (it != readers.end()) {
00882           it->second->touch();
00883           index.push_back(it->second);
00884         } else {
00885           index.push_back(&skipper);
00886         }
00887         if (id == "label" || (id =="id" && inverter.get() == 0)) {
00888           inverter.reset(index.back()->getInverter());
00889           index.back() = inverter.get();
00890         }
00891       }
00892       for (typename MapReaders::iterator it = readers.begin();
00893            it != readers.end(); ++it) {
00894         if (!it->second->touched()) {
00895           ErrorMessage msg;
00896           msg << "Map not found in file: " << it->first;
00897           throw IOParameterError(msg.message());
00898         }
00899       }
00900       while (getline(is, line)) {       
00901         Node node = graph.addNode();
00902         std::istringstream ls(line);
00903         for (int i = 0; i < (int)index.size(); ++i) {
00904           index[i]->read(ls, node);
00905         }
00906       }
00907     }
00908 
00909   public:
00910 
00915     bool isLabelReader() const {
00916       return inverter.get() != 0;
00917     }
00918 
00923     void readLabel(std::istream& is, Node& node) const {
00924       node = inverter->read(is);
00925     } 
00926 
00927   private:
00928 
00929     typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
00930     MapReaders readers;
00931    
00932     Graph& graph;   
00933     std::string name;
00934     _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
00935 
00936     std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
00937   };
00938 
00961   template <typename _Graph, typename _Traits = DefaultReaderTraits>
00962   class EdgeSetReader : public LemonReader::SectionReader {
00963     typedef LemonReader::SectionReader Parent;
00964   public:
00965 
00966     typedef _Graph Graph;
00967     typedef _Traits Traits;
00968     typedef typename Graph::Node Node;
00969     typedef typename Graph::Edge Edge;
00970     typedef typename Traits::Skipper DefaultSkipper;
00971 
00980     template <typename NodeLabelReader>
00981     EdgeSetReader(LemonReader& _reader, 
00982                   Graph& _graph, 
00983                   const NodeLabelReader& _nodeLabelReader, 
00984                   const std::string& _name = std::string(),
00985                   const DefaultSkipper& _skipper = DefaultSkipper()) 
00986       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
00987       checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
00988       nodeLabelReader.reset(new _reader_bits::
00989                          LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
00990     }
00994     virtual ~EdgeSetReader() {
00995       for (typename MapReaders::iterator it = readers.begin(); 
00996            it != readers.end(); ++it) {
00997         delete it->second;
00998       }
00999     }
01000 
01001   private:
01002     EdgeSetReader(const EdgeSetReader&);
01003     void operator=(const EdgeSetReader&);
01004 
01005   public:
01006 
01010     template <typename Map>
01011     EdgeSetReader& readEdgeMap(std::string name, Map& map) {
01012       return _readMap<
01013         typename Traits::template Reader<typename Map::Value>, Map,
01014         typename _reader_bits::Arg<Map>::Type>(name, map);
01015     }
01016 
01017     template <typename Map>
01018     EdgeSetReader& readEdgeMap(std::string name, const Map& map) {
01019       return _readMap<
01020         typename Traits::template Reader<typename Map::Value>, Map,
01021         typename _reader_bits::Arg<Map>::Type>(name, map);
01022     }
01023 
01027     template <typename Reader, typename Map>
01028     EdgeSetReader& readEdgeMap(std::string name, Map& map, 
01029                            const Reader& reader = Reader()) {
01030       return _readMap<Reader, Map,
01031         typename _reader_bits::Arg<Map>::Type>(name, map, reader);
01032     }
01033 
01034     template <typename Reader, typename Map>
01035     EdgeSetReader& readEdgeMap(std::string name, const Map& map, 
01036                                const Reader& reader = Reader()) {
01037       return _readMap<Reader, Map,
01038         typename _reader_bits::Arg<Map>::Type>(name, map, reader);
01039     }
01040 
01041   private:
01042 
01043     template <typename Reader, typename Map, typename MapParameter>
01044     EdgeSetReader& _readMap(std::string name, MapParameter map, 
01045                             const Reader& reader = Reader()) {
01046       checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
01047       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
01048       if (readers.find(name) != readers.end()) {
01049         ErrorMessage msg;
01050         msg << "Multiple read rule for edge map: " << name;
01051         throw IOParameterError(msg.message());
01052       }
01053       readers.insert(
01054         make_pair(name, new _reader_bits::
01055                   MapReader<Edge, Map, Reader>(map, reader)));
01056       return *this;
01057     }
01058 
01059   public:
01060 
01064     template <typename Reader>
01065     EdgeSetReader& skipEdgeMap(std::string name, 
01066                                const Reader& reader = Reader()) {
01067       if (readers.find(name) != readers.end()) {
01068         ErrorMessage msg;
01069         msg << "Multiple read rule for edge map: " << name;
01070         throw IOParameterError(msg.message());
01071       }
01072       readers.insert(make_pair(name, new _reader_bits::
01073                                SkipReader<Edge, Reader>(reader)));
01074       return *this;
01075     }
01076 
01077   protected:
01078 
01084     virtual bool header(const std::string& line) {
01085       std::istringstream ls(line);
01086       std::string command;
01087       std::string id;
01088       ls >> command >> name;
01089       return command == "@edgeset" && name == id;
01090     }
01091 
01095     virtual void read(std::istream& is) {
01096       if (!nodeLabelReader->isLabelReader()) {
01097         throw DataFormatError("Cannot find nodeset or label map");
01098       }
01099       std::vector<_reader_bits::MapReaderBase<Edge>* > index;
01100       std::string line;
01101 
01102       getline(is, line);
01103       std::istringstream ls(line);      
01104       std::string id;
01105       while (ls >> id) {
01106         typename MapReaders::iterator it = readers.find(id);
01107         if (it != readers.end()) {
01108           index.push_back(it->second);
01109           it->second->touch();
01110         } else {
01111           index.push_back(&skipper);
01112         }
01113         if (id == "label" || (id =="id" && inverter.get() == 0)) {
01114           inverter.reset(index.back()->getInverter());
01115           index.back() = inverter.get();
01116         }
01117       }
01118       for (typename MapReaders::iterator it = readers.begin();
01119            it != readers.end(); ++it) {
01120         if (!it->second->touched()) {
01121           ErrorMessage msg;
01122           msg << "Map not found in file: " << it->first;
01123           throw IOParameterError(msg.message());
01124         }
01125       }
01126       while (getline(is, line)) {       
01127         std::istringstream ls(line);
01128         Node from = nodeLabelReader->read(ls);
01129         Node to = nodeLabelReader->read(ls);
01130         Edge edge = graph.addEdge(from, to);
01131         for (int i = 0; i < (int)index.size(); ++i) {
01132           index[i]->read(ls, edge);
01133         }
01134       }
01135     }
01136 
01137   public:
01138 
01143     bool isLabelReader() const {
01144       return inverter.get() != 0;
01145     }
01146 
01151     void readLabel(std::istream& is, Edge& edge) const {
01152       edge = inverter->read(is);
01153     } 
01154 
01155   private:
01156 
01157     typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
01158     MapReaders readers;
01159    
01160     Graph& graph;   
01161     std::string name;
01162     _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
01163 
01164     std::auto_ptr<_reader_bits::MapInverterBase<Edge> > inverter;
01165     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
01166   };
01167 
01195   template <typename _Graph, typename _Traits = DefaultReaderTraits>
01196   class UEdgeSetReader : public LemonReader::SectionReader {
01197     typedef LemonReader::SectionReader Parent;
01198   public:
01199 
01200     typedef _Graph Graph;
01201     typedef _Traits Traits;
01202     typedef typename Graph::Node Node;
01203     typedef typename Graph::Edge Edge;
01204     typedef typename Graph::UEdge UEdge;
01205     typedef typename Traits::Skipper DefaultSkipper;
01206 
01215     template <typename NodeLabelReader>
01216     UEdgeSetReader(LemonReader& _reader, 
01217                        Graph& _graph, 
01218                        const NodeLabelReader& _nodeLabelReader, 
01219                        const std::string& _name = std::string(),
01220                        const DefaultSkipper& _skipper = DefaultSkipper()) 
01221       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
01222       checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
01223       nodeLabelReader.reset(new _reader_bits::
01224                          LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
01225     }
01229     virtual ~UEdgeSetReader() {
01230       for (typename MapReaders::iterator it = readers.begin(); 
01231            it != readers.end(); ++it) {
01232         delete it->second;
01233       }
01234     }
01235 
01236   private:
01237     UEdgeSetReader(const UEdgeSetReader&);
01238     void operator=(const UEdgeSetReader&);
01239 
01240   public:
01241 
01245     template <typename Map>
01246     UEdgeSetReader& readUEdgeMap(std::string name, Map& map) {
01247       return _readMap<
01248         typename Traits::template Reader<typename Map::Value>, Map, 
01249         typename _reader_bits::Arg<Map>::Type>(name, map);
01250     }
01251 
01252     template <typename Map>
01253     UEdgeSetReader& readUEdgeMap(std::string name, const Map& map) {
01254       return _readMap<
01255         typename Traits::template Reader<typename Map::Value>, Map, 
01256         typename _reader_bits::Arg<Map>::Type>(name, map);
01257     }
01258 
01262     template <typename Reader, typename Map>
01263     UEdgeSetReader& readUEdgeMap(std::string name, Map& map, 
01264                                          const Reader& reader = Reader()) {
01265       return _readMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
01266         (name, map, reader);
01267     }
01268 
01269     template <typename Reader, typename Map>
01270     UEdgeSetReader& readUEdgeMap(std::string name, const Map& map, 
01271                                          const Reader& reader = Reader()) {
01272       return _readMap<Reader, Map, typename _reader_bits::Arg<Map>::Type >
01273         (name, map, reader);
01274     }
01275 
01276   private:
01277 
01278     template <typename Reader, typename Map, typename MapParameter>
01279     UEdgeSetReader& _readMap(std::string name, MapParameter map,
01280                                  const Reader& reader = Reader()) {
01281       checkConcept<concept::WriteMap<UEdge, typename Map::Value>, Map>();
01282       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
01283       if (readers.find(name) != readers.end()) {
01284         ErrorMessage msg;
01285         msg << "Multiple read rule for edge map: " << name;
01286         throw IOParameterError(msg.message());
01287       }
01288       readers.insert(
01289         make_pair(name, new _reader_bits::
01290                   MapReader<UEdge, Map, Reader>(map, reader)));
01291       return *this;
01292     }
01293 
01294   public:
01295 
01299     template <typename Reader>
01300     UEdgeSetReader& skipUEdgeMap(std::string name, 
01301                                          const Reader& reader = Reader()) {
01302       if (readers.find(name) != readers.end()) {
01303         ErrorMessage msg;
01304         msg << "Multiple read rule for node map: " << name;
01305         throw IOParameterError(msg.message());
01306       }
01307       readers.insert(make_pair(name, new _reader_bits::
01308                                SkipReader<UEdge, Reader>(reader)));
01309       return *this;
01310     }
01311 
01315     template <typename Map>
01316     UEdgeSetReader& readEdgeMap(std::string name, Map& map) {
01317       return _readDirMap<
01318         typename Traits::template Reader<typename Map::Value>, Map,
01319         typename _reader_bits::Arg<Map>::Type>(name, map);
01320     }
01321 
01322     template <typename Map>
01323     UEdgeSetReader& readEdgeMap(std::string name, const Map& map) {
01324       return _readDirMap<
01325         typename Traits::template Reader<typename Map::Value>, Map,
01326         typename _reader_bits::Arg<Map>::Type>(name, map);
01327     }
01328 
01332     template <typename Reader, typename Map>
01333     UEdgeSetReader& readEdgeMap(std::string name, Map& map, 
01334                                     const Reader& reader = Reader()) {
01335       return _readDirMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
01336         (name, map, reader);
01337     }
01338 
01339     template <typename Reader, typename Map>
01340     UEdgeSetReader& readEdgeMap(std::string name, const Map& map, 
01341                                     const Reader& reader = Reader()) {
01342       return _readDirMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
01343         (name, map, reader);
01344     }
01345 
01346   private:
01347 
01348     template <typename Reader, typename Map, typename MapParameter>
01349     UEdgeSetReader& _readDirMap(std::string name, MapParameter map,
01350                                     const Reader& reader = Reader()) { 
01351       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
01352       checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
01353       readMap("+" + name, 
01354               _reader_bits::forwardComposeMap(graph, map), reader);
01355       readMap("-" + name, 
01356               _reader_bits::backwardComposeMap(graph, map), reader);
01357       return *this;      
01358     }
01359 
01360   public:
01361 
01365     template <typename Reader>
01366     UEdgeSetReader& skipEdgeMap(std::string name, 
01367                                     const Reader& reader = Reader()) {
01368       skipMap("+" + name, reader);
01369       skipMap("-" + name, reader);
01370       return *this;
01371     }
01372 
01373   protected:
01374 
01380     virtual bool header(const std::string& line) {
01381       std::istringstream ls(line);
01382       std::string command;
01383       std::string id;
01384       ls >> command >> name;
01385       return command == "@uedgeset" && name == id;
01386     }
01387 
01391     virtual void read(std::istream& is) {
01392       if (!nodeLabelReader->isLabelReader()) {
01393         throw DataFormatError("Cannot find nodeset or label map");
01394       }
01395       std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
01396       std::string line;
01397 
01398       getline(is, line);
01399       std::istringstream ls(line);      
01400       std::string id;
01401       while (ls >> id) {
01402         typename MapReaders::iterator it = readers.find(id);
01403         if (it != readers.end()) {
01404           index.push_back(it->second);
01405           it->second->touch();
01406         } else {
01407           index.push_back(&skipper);
01408         }
01409         if (id == "label" || (id =="id" && inverter.get() == 0)) {
01410           inverter.reset(index.back()->getInverter());
01411           index.back() = inverter.get();
01412         }
01413       }
01414       for (typename MapReaders::iterator it = readers.begin();
01415            it != readers.end(); ++it) {
01416         if (!it->second->touched()) {
01417           ErrorMessage msg;
01418           msg << "Map not found in file: " << it->first;
01419           throw IOParameterError(msg.message());
01420         }
01421       }
01422       while (getline(is, line)) {       
01423         std::istringstream ls(line);
01424         Node from = nodeLabelReader->read(ls);
01425         Node to = nodeLabelReader->read(ls);
01426         UEdge edge = graph.addEdge(from, to);
01427         for (int i = 0; i < (int)index.size(); ++i) {
01428           index[i]->read(ls, edge);
01429         }
01430       }
01431     }
01432 
01433   public:
01434 
01439     bool isLabelReader() const {
01440       return inverter.get() != 0;
01441     }
01442 
01447     void readLabel(std::istream& is, UEdge& uEdge) const {
01448       uEdge = inverter->read(is);
01449     } 
01450 
01457     void readLabel(std::istream& is, Edge& edge) const {
01458       char c;
01459       is >> c;
01460       UEdge uEdge = inverter->read(is);
01461       if (c == '+') {
01462         edge = graph.direct(uEdge, true);
01463       } else if (c == '-') {
01464         edge = graph.direct(uEdge, false);
01465       } else {
01466         throw DataFormatError("Wrong id format for edge "
01467                               "in undirected edgeset");
01468       }
01469     } 
01470 
01471   private:
01472 
01473     typedef std::map<std::string, 
01474                      _reader_bits::MapReaderBase<UEdge>*> MapReaders;
01475     MapReaders readers;
01476    
01477     Graph& graph;   
01478     std::string name;
01479     _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
01480 
01481     std::auto_ptr<_reader_bits::MapInverterBase<UEdge> > inverter;
01482     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
01483   };
01484 
01495   template <typename _Graph>
01496   class NodeReader : public LemonReader::SectionReader {
01497     typedef LemonReader::SectionReader Parent;
01498     typedef _Graph Graph;
01499     typedef typename Graph::Node Node;
01500   public:
01501     
01508     template <typename _LabelReader>
01509     NodeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
01510                const std::string& _name = std::string()) 
01511       : Parent(_reader), name(_name) {
01512       checkConcept<_reader_bits::ItemLabelReader<Node>, _LabelReader>();
01513       nodeLabelReader.reset(new _reader_bits::
01514                          LabelReader<Node, _LabelReader>(_labelReader));
01515     }
01516 
01520     virtual ~NodeReader() {}
01521 
01522   private:
01523     NodeReader(const NodeReader&);
01524     void operator=(const NodeReader&);
01525 
01526   public:
01527 
01531     void readNode(const std::string& name, Node& item) {
01532       if (readers.find(name) != readers.end()) {
01533         ErrorMessage msg;
01534         msg << "Multiple read rule for node: " << name;
01535         throw IOParameterError(msg.message());
01536       }
01537       readers.insert(make_pair(name, _reader_bits::ItemStore<Node>(item)));
01538     }
01539 
01540   protected:
01541 
01547     virtual bool header(const std::string& line) {
01548       std::istringstream ls(line);
01549       std::string command;
01550       std::string id;
01551       ls >> command >> name;
01552       return command == "@nodes" && name == id;
01553     }
01554 
01558     virtual void read(std::istream& is) {
01559       if (!nodeLabelReader->isLabelReader()) {
01560         throw DataFormatError("Cannot find nodeset or label map");
01561       }
01562       std::string line;
01563       while (getline(is, line)) {
01564         std::istringstream ls(line);
01565         std::string id;
01566         ls >> id;
01567         typename NodeReaders::iterator it = readers.find(id);
01568         if (it != readers.end()) {
01569           it->second.read(nodeLabelReader->read(ls));
01570           it->second.touch();
01571         }       
01572       }
01573       for (typename NodeReaders::iterator it = readers.begin();
01574            it != readers.end(); ++it) {
01575         if (!it->second.touched()) {
01576           ErrorMessage msg;
01577           msg << "Node not found in file: " << it->first;
01578           throw IOParameterError(msg.message());
01579         }
01580       }
01581     }
01582     
01583   private:
01584 
01585     std::string name;
01586 
01587     typedef std::map<std::string, _reader_bits::ItemStore<Node> > NodeReaders;
01588     NodeReaders readers;
01589     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
01590   };
01591 
01602   template <typename _Graph>
01603   class EdgeReader : public LemonReader::SectionReader {
01604     typedef LemonReader::SectionReader Parent;
01605     typedef _Graph Graph;
01606     typedef typename Graph::Edge Edge;
01607   public:
01608     
01615     template <typename _LabelReader>
01616     EdgeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
01617                const std::string& _name = std::string()) 
01618       : Parent(_reader), name(_name) {
01619       checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
01620       edgeLabelReader.reset(new _reader_bits::
01621                          LabelReader<Edge, _LabelReader>(_labelReader));
01622     }
01623 
01627     virtual ~EdgeReader() {}
01628   private:
01629     EdgeReader(const EdgeReader&);
01630     void operator=(const EdgeReader&);
01631 
01632   public:
01633 
01637     void readEdge(const std::string& name, Edge& item) {
01638       if (readers.find(name) != readers.end()) {
01639         ErrorMessage msg;
01640         msg << "Multiple read rule for edge: " << name;
01641         throw IOParameterError(msg.message());
01642       }
01643       readers.insert(make_pair(name, _reader_bits::ItemStore<Edge>(item)));
01644     }
01645 
01646   protected:
01647 
01653     virtual bool header(const std::string& line) {
01654       std::istringstream ls(line);
01655       std::string command;
01656       std::string id;
01657       ls >> command >> name;
01658       return command == "@edges" && name == id;
01659     }
01660 
01664     virtual void read(std::istream& is) {
01665       if (!edgeLabelReader->isLabelReader()) {
01666         throw DataFormatError("Cannot find edgeset or label map");
01667       }
01668       std::string line;
01669       while (getline(is, line)) {
01670         std::istringstream ls(line);
01671         std::string id;
01672         ls >> id;
01673         typename EdgeReaders::iterator it = readers.find(id);
01674         if (it != readers.end()) {
01675           it->second.read(edgeLabelReader->read(ls));
01676           it->second.touch();
01677         }       
01678       }
01679       for (typename EdgeReaders::iterator it = readers.begin();
01680            it != readers.end(); ++it) {
01681         if (!it->second.touched()) {
01682           ErrorMessage msg;
01683           msg << "Edge not found in file: " << it->first;
01684           throw IOParameterError(msg.message());
01685         }
01686       }
01687     }
01688     
01689   private:
01690 
01691     std::string name;
01692 
01693     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
01694     EdgeReaders readers;
01695     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
01696   };
01697 
01708   template <typename _Graph>
01709   class UEdgeReader : public LemonReader::SectionReader {
01710     typedef LemonReader::SectionReader Parent;
01711     typedef _Graph Graph;
01712     typedef typename Graph::Edge Edge;
01713     typedef typename Graph::UEdge UEdge;
01714   public:
01715     
01723     template <typename _LabelReader>
01724     UEdgeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
01725                const std::string& _name = std::string()) 
01726       : Parent(_reader), name(_name) {
01727       checkConcept<_reader_bits::ItemLabelReader<UEdge>, _LabelReader>();
01728       checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
01729       uEdgeLabelReader.reset(new _reader_bits::
01730                               LabelReader<UEdge, _LabelReader>(_labelReader));
01731       edgeLabelReader.reset(new _reader_bits::
01732                          LabelReader<Edge, _LabelReader>(_labelReader));
01733     }
01734 
01738     virtual ~UEdgeReader() {}
01739   private:
01740     UEdgeReader(const UEdgeReader&);
01741     void operator=(const UEdgeReader&);
01742 
01743   public:
01744 
01748     void readUEdge(const std::string& name, UEdge& item) {
01749       if (uEdgeReaders.find(name) != uEdgeReaders.end()) {
01750         ErrorMessage msg;
01751         msg << "Multiple read rule for undirected edge: " << name;
01752         throw IOParameterError(msg.message());
01753       }
01754       uEdgeReaders.insert(make_pair(name, _reader_bits::
01755                                         ItemStore<UEdge>(item)));
01756     }
01757 
01761     void readEdge(const std::string& name, Edge& item) {
01762       if (edgeReaders.find(name) != edgeReaders.end()) {
01763         ErrorMessage msg;
01764         msg << "Multiple read rule for edge: " << name;
01765         throw IOParameterError(msg.message());
01766       }
01767       edgeReaders.insert(make_pair(name, _reader_bits::ItemStore<Edge>(item)));
01768     }
01769 
01770   protected:
01771 
01777     virtual bool header(const std::string& line) {
01778       std::istringstream ls(line);
01779       std::string command;
01780       std::string id;
01781       ls >> command >> name;
01782       return command == "@uedges" && name == id;
01783     }
01784 
01788     virtual void read(std::istream& is) {
01789       if (!edgeLabelReader->isLabelReader()) {
01790         throw DataFormatError("Cannot find undirected edgeset or label map");
01791       }
01792       if (!uEdgeLabelReader->isLabelReader()) {
01793         throw DataFormatError("Cannot find undirected edgeset or label map");
01794       }
01795       std::string line;
01796       while (getline(is, line)) {
01797         std::istringstream ls(line);
01798         std::string id;
01799         ls >> id;
01800         {
01801           typename UEdgeReaders::iterator it = uEdgeReaders.find(id);
01802           if (it != uEdgeReaders.end()) {
01803             it->second.read(uEdgeLabelReader->read(ls));
01804             it->second.touch();
01805             continue;
01806           }     
01807         } {
01808           typename EdgeReaders::iterator it = edgeReaders.find(id);
01809           if (it != edgeReaders.end()) {
01810             it->second.read(edgeLabelReader->read(ls));
01811             it->second.touch();
01812             continue;
01813           }     
01814         }
01815       }
01816       for (typename EdgeReaders::iterator it = edgeReaders.begin();
01817            it != edgeReaders.end(); ++it) {
01818         if (!it->second.touched()) {
01819           ErrorMessage msg;
01820           msg << "Edge not found in file: " << it->first;
01821           throw IOParameterError(msg.message());
01822         }
01823       }
01824       for (typename UEdgeReaders::iterator it = uEdgeReaders.begin();
01825            it != uEdgeReaders.end(); ++it) {
01826         if (!it->second.touched()) {
01827           ErrorMessage msg;
01828           msg << "UEdge not found in file: " << it->first;
01829           throw IOParameterError(msg.message());
01830         }
01831       }
01832     }
01833     
01834   private:
01835 
01836     std::string name;
01837 
01838     typedef std::map<std::string, 
01839                      _reader_bits::ItemStore<UEdge> > UEdgeReaders;
01840     UEdgeReaders uEdgeReaders;
01841     std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uEdgeLabelReader;
01842 
01843     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
01844     EdgeReaders edgeReaders;
01845     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
01846   };
01847 
01859   template <typename _Traits = DefaultReaderTraits>
01860   class AttributeReader : public LemonReader::SectionReader {
01861     typedef LemonReader::SectionReader Parent;
01862     typedef _Traits Traits; 
01863   public:
01869     AttributeReader(LemonReader& _reader, 
01870                     const std::string& _name = std::string()) 
01871       : Parent(_reader), name(_name) {}
01872 
01876     virtual ~AttributeReader() {
01877       for (typename Readers::iterator it = readers.begin(); 
01878            it != readers.end(); ++it) {
01879         delete it->second;
01880       }
01881     }
01882 
01883   private:
01884     AttributeReader(const AttributeReader&);
01885     void operator=(AttributeReader&);
01886 
01887   public:
01891     template <typename Value>
01892     AttributeReader& readAttribute(const std::string& id, Value& value) {
01893       return readAttribute<typename Traits::template Reader<Value> >
01894         (id, value);
01895     }
01896 
01900     template <typename Reader, typename Value>
01901     AttributeReader& readAttribute(const std::string& name, Value& value,
01902                                    const Reader& reader = Reader()) {
01903       checkConcept<_reader_bits::ItemReader<Value>, Reader>();
01904       if (readers.find(name) != readers.end()) {
01905         ErrorMessage msg;
01906         msg << "Multiple read rule for attribute: " << name;
01907         throw IOParameterError(msg.message());
01908       }
01909       readers.insert(make_pair(name, new _reader_bits::
01910                                ValueReader<Value, Reader>(value, reader)));
01911       return *this;
01912     }
01913 
01914   protected:
01915 
01921     bool header(const std::string& line) {
01922       std::istringstream ls(line);
01923       std::string command;
01924       std::string id;
01925       ls >> command >> name;
01926       return command == "@attributes" && name == id;
01927     }
01928 
01932     void read(std::istream& is) {
01933       std::string line;
01934       while (getline(is, line)) {
01935         std::istringstream ls(line);
01936         std::string id;
01937         ls >> id;
01938         typename Readers::iterator it = readers.find(id);
01939         if (it != readers.end()) {
01940           it->second->read(ls);
01941           it->second->touch();
01942         }
01943       }
01944       for (typename Readers::iterator it = readers.begin();
01945            it != readers.end(); ++it) {
01946         if (!it->second->touched()) {
01947           ErrorMessage msg;
01948           msg << "Attribute not found in file: " << it->first;
01949           throw IOParameterError(msg.message());
01950         }       
01951       }
01952     }    
01953 
01954   private:
01955     std::string name;
01956 
01957     typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers;
01958     Readers readers;  
01959   };
01960 
01972   class ContentReader : public LemonReader::SectionReader {
01973     typedef LemonReader::SectionReader Parent;
01974   public:
01978     ContentReader(LemonReader& _reader) : Parent(_reader) {}
01979 
01983     virtual ~ContentReader() {}
01984 
01988     int nodeSetNum() const {
01989       return nodesets.size();
01990     }
01991 
01995     std::string nodeSetName(int index) const {
01996       return nodesets[index].name;
01997     }
01998 
02002     const std::vector<std::string>& nodeSetMaps(int index) const {
02003       return nodesets[index].items;
02004     }
02005 
02009     int edgeSetNum() const {
02010       return edgesets.size();
02011     }
02012 
02016     std::string edgeSetName(int index) const {
02017       return edgesets[index].name;
02018     }
02019 
02023     const std::vector<std::string>& edgeSetMaps(int index) const {
02024       return edgesets[index].items;
02025     }
02026 
02030     int uEdgeSetNum() const {
02031       return uedgesets.size();
02032     }
02033 
02038     std::string uEdgeSetName(int index) const {
02039       return uedgesets[index].name;
02040     }
02041 
02046     const std::vector<std::string>& uEdgeSetMaps(int index) const {
02047       return uedgesets[index].items;
02048     }
02049 
02053     int nodesNum() const {
02054       return nodes.size();
02055     }
02056 
02061     std::string nodesName(int index) const {
02062       return nodes[index].name;
02063     }
02064 
02069     const std::vector<std::string>& nodesItems(int index) const {
02070       return nodes[index].items;
02071     }
02072 
02076     int edgesNum() const {
02077       return edges.size();
02078     }
02079 
02084     std::string edgesName(int index) const {
02085       return edges[index].name;
02086     }
02087 
02092     const std::vector<std::string>& edgesItems(int index) const {
02093       return edges[index].items;
02094     }
02095  
02100     int uEdgesNum() const {
02101       return uedges.size();
02102     }
02103 
02109     std::string uEdgesName(int index) const {
02110       return uedges[index].name;
02111     }
02112 
02118     const std::vector<std::string>& uEdgesItems(int index) const {
02119       return uedges[index].items;
02120     }
02121 
02122  
02126     int attributesNum() const {
02127       return attributes.size();
02128     }
02129 
02134     std::string attributesName(int index) const {
02135       return attributes[index].name;
02136     }
02137 
02141     const std::vector<std::string>& attributesItems(int index) const {
02142       return attributes[index].items;
02143     }
02144 
02145     const std::vector<std::string>& otherSections() const {
02146       return sections;
02147     }
02148 
02149   protected:
02150     
02155     bool header(const std::string& line) {
02156       std::istringstream ls(line);
02157       std::string command, name;
02158       ls >> command >> name;
02159       if (command == "@nodeset") {
02160         current = command;
02161         nodesets.push_back(SectionInfo(name));
02162       } else if (command == "@edgeset") {
02163         current = command;
02164         edgesets.push_back(SectionInfo(name));
02165       } else if (command == "@uedgeset") {
02166         current = command;
02167         uedgesets.push_back(SectionInfo(name));
02168       } else if (command == "@nodes") {
02169         current = command;
02170         nodes.push_back(SectionInfo(name));
02171       } else if (command == "@edges") {
02172         current = command;
02173         edges.push_back(SectionInfo(name));
02174       } else if (command == "@uedges") {
02175         current = command;
02176         uedges.push_back(SectionInfo(name));
02177       } else if (command == "@attributes") {
02178         current = command;
02179         attributes.push_back(SectionInfo(name));
02180       } else {
02181         sections.push_back(line);
02182         return false;
02183       }
02184       return true;
02185     }
02186 
02190     void read(std::istream& is) {
02191       if (current == "@nodeset") {
02192         readMapNames(is, nodesets.back().items);
02193       } else if (current == "@edgeset") {
02194         readMapNames(is, edgesets.back().items);
02195       } else if (current == "@uedgeset") {
02196         readMapNames(is, uedgesets.back().items);
02197       } else if (current == "@nodes") {
02198         readItemNames(is, nodes.back().items);
02199       } else if (current == "@edges") {
02200         readItemNames(is, edges.back().items);
02201       } else if (current == "@uedges") {
02202         readItemNames(is, uedges.back().items);
02203       } else if (current == "@attributes") {
02204         readItemNames(is, attributes.back().items);
02205       }
02206     }    
02207 
02208   private:
02209 
02210     void readMapNames(std::istream& is, std::vector<std::string>& maps) {
02211       std::string line, name;
02212       std::getline(is, line);
02213       std::istringstream ls(line);
02214       while (ls >> name) {
02215         maps.push_back(name);
02216       }
02217       while (getline(is, line));
02218     }
02219 
02220     void readItemNames(std::istream& is, std::vector<std::string>& maps) {
02221       std::string line, name;
02222       while (std::getline(is, line)) {
02223         std::istringstream ls(line);
02224         ls >> name;
02225         maps.push_back(name);
02226       }
02227     }
02228 
02229     struct SectionInfo {
02230       std::string name;
02231       std::vector<std::string> items;
02232 
02233       SectionInfo(const std::string& _name) : name(_name) {}
02234     };
02235 
02236     std::vector<SectionInfo> nodesets;
02237     std::vector<SectionInfo> edgesets;
02238     std::vector<SectionInfo> uedgesets;
02239 
02240     std::vector<SectionInfo> nodes;
02241     std::vector<SectionInfo> edges;
02242     std::vector<SectionInfo> uedges;
02243 
02244     std::vector<SectionInfo> attributes;
02245 
02246     std::vector<std::string> sections;
02247 
02248     std::string current;
02249 
02250   };
02251 
02252 }
02253 #endif

Generated on Fri Feb 3 18:38:18 2006 for LEMON by  doxygen 1.4.6