COIN-OR::LEMON - Graph Library

Changeset 1408:892c29484414 in lemon-0.x


Ignore:
Timestamp:
05/09/05 13:24:26 (19 years ago)
Author:
Balazs Dezso
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@1875
Message:

New graph reader interface.

Location:
src/lemon
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • src/lemon/Makefile.am

    r1402 r1408  
    5353        concept_check.h \
    5454        utility.h \
     55        lemon_reader.h \
    5556        graph_reader.h \
    5657        graph_writer.h \
     
    6566        bits/clearable_graph_extender.h \
    6667        bits/erasable_graph_extender.h \
    67         bits/undir_graph_extender.h
     68        bits/undir_graph_extender.h \
     69        bits/item_reader.h
    6870
    6971noinst_HEADERS = \
  • src/lemon/graph_reader.h

    r1396 r1408  
    2323
    2424#include <iostream>
    25 #include <sstream>
    26 
    27 #include <map>
    28 #include <vector>
    29 
    30 #include <memory>
    3125
    3226#include <lemon/error.h>
    33 
     27#include <lemon/lemon_reader.h>
    3428
    3529namespace lemon {
     
    3832  /// @{
    3933
    40   /// \brief Standard ReaderTraits for the GraphReader class.
    41   ///
    42   /// Standard ReaderTraits for the GraphReader class.
    43   /// It defines standard reading method for all type of value.
    44   /// \author Balazs Dezso
    45   struct DefaultReaderTraits {
    46 
    47     /// \brief Template class for reading an value.
    48     ///
    49     /// Template class for reading an value.
    50     /// \author Balazs Dezso
    51     template <typename _Value>
    52     struct Reader {
    53       /// The value type.
    54       typedef _Value Value;
    55       /// \brief Reads a value from the given stream.
    56       ///
    57       /// Reads a value from the given stream.
    58       void read(std::istream& is, Value& value) {
    59         if (!(is >> value))
    60           throw DataFormatError("Default reader format exception");
    61       }
    62     };
    63 
    64     /// \brief Returns wheter this name is an ID map name.
    65     ///
    66     /// Returns wheter this name is an ID map name.
    67     static bool idMapName(const std::string& name) {
    68       return name == "id";
    69     }
    70 
    71     /// The reader class for the not needed maps.
    72     typedef Reader<std::string> DefaultReader;
    73 
    74   };
    75 
    76   /// \brief Reader class for quoted strings.
    77   ///
    78   /// Reader class for quoted strings. It can process the escape
    79   /// sequences in the string.
    80   /// \author Balazs Dezso
    81   class QuotedStringReader {
    82   public:
    83     typedef std::string Value;
    84    
    85     /// \brief Constructor for the reader.
    86     ///
    87     /// Constructor for the reader. If the given parameter is true
    88     /// the reader processes the escape sequences.
    89     QuotedStringReader(bool _escaped = true) : escaped(_escaped) {}
    90    
    91     /// \brief Reads a quoted string from the given stream.
    92     ///
    93     /// Reads a quoted string from the given stream.
    94     void read(std::istream& is, std::string& value) {
    95       char c;
    96       value.clear();
    97       is >> std::ws;
    98       if (!is.get(c) || c != '\"')
    99         throw DataFormatError("Quoted string format error");
    100       while (is.get(c) && c != '\"') {
    101         if (escaped && c == '\\') {
    102           value += readEscape(is);
    103         } else {
    104           value += c;
    105         }
    106       }
    107       if (!is) throw DataFormatError("Quoted string format error");
    108     }
    109 
    110   private:
    111    
    112     static char readEscape(std::istream& is) {
    113       char c;
    114       switch (is.get(c), c) {
    115       case '\\':
    116         return '\\';
    117       case '\"':
    118         return '\"';
    119       case '\'':
    120         return '\'';
    121       case '\?':
    122         return '\?';
    123       case 'a':
    124         return '\a';
    125       case 'b':
    126         return '\b';
    127       case 'f':
    128         return '\f';
    129       case 'n':
    130         return '\n';
    131       case 'r':
    132         return '\r';
    133       case 't':
    134         return '\t';
    135       case 'v':
    136         return '\v';
    137       case 'x':
    138         {
    139           int code;
    140           if (!is.get(c) || !isHex(c))
    141             throw DataFormatError("Escape format error");
    142           else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
    143           else code = code * 16 + valueHex(c);
    144           return code;
    145         }
    146       default:
    147         {
    148           int code;
    149           if (!isOct(c))
    150             throw DataFormatError("Escape format error");
    151           else if (code = valueOct(c), !is.get(c) || !isOct(c))
    152             is.putback(c);
    153           else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
    154             is.putback(c);
    155           else code = code * 8 + valueOct(c);
    156           return code;
    157         }             
    158       }
    159     }
    160 
    161     static bool isOct(char c) {
    162       return '0' <= c && c <='7';
    163     }
    164    
    165     static int valueOct(char c) {
    166       return c - '0';
    167     }
    168 
    169    static bool isHex(char c) {
    170       return ('0' <= c && c <= '9') ||
    171         ('a' <= c && c <= 'z') ||
    172         ('A' <= c && c <= 'Z');
    173     }
    174    
    175     static int valueHex(char c) {
    176       if ('0' <= c && c <= '9') return c - '0';
    177       if ('a' <= c && c <= 'z') return c - 'a' + 10;
    178       return c - 'A' + 10;
    179     }
    180 
    181     bool escaped;
    182   };
    183 
    184   class GUIReader {
    185   public:
    186     virtual void read(std::istream& is) = 0;
    187   };
    188 
    18934  /// \brief The graph reader class.
    190   ///
    19135  ///
    19236  /// The given file format may contain several maps and labeled nodes or
     
    23074  /// \endcode
    23175  ///
    232   /// With \c readNode() and \c readEdge() functions you can read labeled Nodes
    233   /// and Edges.
     76  /// With \c readNode() and \c readEdge() functions you can read
     77  /// labeled Nodes and Edges.
    23478  ///
    23579  /// \code
     
    23983  /// reader.readEdge("observed", edge);
    24084  /// \endcode
     85  ///
     86  /// With the \c readAttribute() functions you can read an attribute
     87  /// in a variable. You can specify the reader for the attribute as
     88  /// the nodemaps.
    24189  ///
    24290  /// After you give all read commands you must call the \c run() member
     
    261109
    262110    typedef _ReaderTraits ReaderTraits;
    263     typedef typename ReaderTraits::DefaultReader DefaultReader;
     111    typedef typename ReaderTraits::Skipper DefaultSkipper;
    264112
    265113    /// \brief Construct a new GraphReader.
     
    268116    /// and it use the given reader as the default skipper.
    269117    GraphReader(std::istream& _is, Graph& _graph,
    270                 const DefaultReader& _reader = DefaultReader())
    271       : gui_reader(0), is(_is), graph(_graph),
    272         nodeSkipper(_reader), edgeSkipper(_reader) {}
     118                const DefaultSkipper& _skipper = DefaultSkipper())
     119      : reader(new LemonReader(_is)), own_reader(true),
     120        graph(_graph), skipper(_skipper),
     121        nodeset_reader(*reader, graph, std::string(), skipper),
     122        edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
     123        node_reader(*reader, nodeset_reader, std::string()),
     124        edge_reader(*reader, edgeset_reader, std::string()),
     125        attribute_reader(*reader, std::string()) {}
     126
     127    /// \brief Construct a new GraphReader.
     128    ///
     129    /// Construct a new GraphReader. It reads into the given graph
     130    /// and it use the given reader as the default skipper.
     131    GraphReader(const std::string& _filename, Graph& _graph,
     132                const DefaultSkipper& _skipper = DefaultSkipper())
     133      : reader(new LemonReader(_filename)), own_reader(true),
     134        graph(_graph), skipper(_skipper),
     135        nodeset_reader(*reader, graph, std::string(), skipper),
     136        edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
     137        node_reader(*reader, nodeset_reader, std::string()),
     138        edge_reader(*reader, edgeset_reader, std::string()),
     139        attribute_reader(*reader, std::string()) {}
     140
     141    /// \brief Construct a new GraphReader.
     142    ///
     143    /// Construct a new GraphReader. It reads into the given graph
     144    /// and it use the given reader as the default skipper.
     145    GraphReader(LemonReader& _reader, Graph& _graph,
     146                const DefaultSkipper& _skipper = DefaultSkipper())
     147      : reader(_reader), own_reader(false),
     148        graph(_graph), skipper(_skipper),
     149        nodeset_reader(*reader, graph, std::string(), skipper),
     150        edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
     151        node_reader(*reader, nodeset_reader, std::string()),
     152        edge_reader(*reader, edgeset_reader, std::string()),
     153        attribute_reader(*reader, std::string()) {}
    273154
    274155    /// \brief Destruct the graph reader.
     
    276157    /// Destruct the graph reader.
    277158    ~GraphReader() {
    278       for (typename NodeMapReaders::iterator it = node_map_readers.begin();
    279            it != node_map_readers.end(); ++it) {
    280         delete it->second;
    281       }
    282 
    283       for (typename EdgeMapReaders::iterator it = edge_map_readers.begin();
    284            it != edge_map_readers.end(); ++it) {
    285         delete it->second;
    286       }
    287 
     159      if (own_reader)
     160        delete reader;
    288161    }
    289162
     
    293166    template <typename Map>
    294167    GraphReader& readNodeMap(std::string name, Map& map) {
    295       return readNodeMap<typename ReaderTraits::template
    296         Reader<typename Map::Value>, Map>(name, map);
     168      nodeset_reader.readMap(name, map);
     169      return *this;
    297170    }
    298171
     
    303176    GraphReader& readNodeMap(std::string name, Map& map,
    304177                             const Reader& reader = Reader()) {
    305       if (node_map_readers.find(name) != node_map_readers.end()) {
    306         ErrorMessage msg;
    307         msg << "Multiple read rule for node map: " << name;
    308         throw IOParameterError(msg.message());
    309       }
    310       node_map_readers.insert(
    311         make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
     178      nodeset_reader.readMap(name, map, reader);
    312179      return *this;
    313180    }
     
    319186    GraphReader& skipNodeMap(std::string name,
    320187                             const Reader& reader = Reader()) {
    321       if (node_map_readers.find(name) != node_map_readers.end()) {
    322         ErrorMessage msg;
    323         msg << "Multiple read rule for node map: " << name;
    324         throw IOParameterError(msg.message());
    325       }
    326       node_map_readers.insert(
    327         make_pair(name, new SkipReader<Node, Reader>(reader)));
     188      nodeset_reader.skipMap(name, reader);
    328189      return *this;
    329190    }
     
    334195    template <typename Map>
    335196    GraphReader& readEdgeMap(std::string name, Map& map) {
    336       return readEdgeMap<typename ReaderTraits::template
    337         Reader<typename Map::Value>, Map>(name, map);
     197      edgeset_reader.readMap(name, map);
     198      return *this;
    338199    }
    339200
     
    345206    GraphReader& readEdgeMap(std::string name, Map& map,
    346207                             const Reader& reader = Reader()) {
    347       if (edge_map_readers.find(name) != edge_map_readers.end()) {
    348         ErrorMessage msg;
    349         msg << "Multiple read rule for edge map: " << name;
    350         throw IOParameterError(msg.message());
    351       }
    352       edge_map_readers.insert(
    353         make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
     208      edgeset_reader.readMap(name, map, reader);
    354209      return *this;
    355210    }
     
    361216    GraphReader& skipEdgeMap(std::string name,
    362217                             const Reader& reader = Reader()) {
    363       if (edge_map_readers.find(name) != edge_map_readers.end()) {
    364         ErrorMessage msg;
    365         msg << "Multiple read rule for edge map: " << name;
    366         throw IOParameterError(msg.message());
    367       }
    368       edge_map_readers.insert(
    369         make_pair(name, new SkipReader<Edge, Reader>(reader)));
     218
     219      edgeset_reader.skipMap(name, reader);
    370220      return *this;
    371221    }
     
    375225    /// Add a new labeled node reader for the reader.
    376226    GraphReader& readNode(std::string name, Node& node) {
    377       if (node_readers.find(name) != node_readers.end()) {
    378         ErrorMessage msg;
    379         msg << "Multiple read rule for node: " << name;
    380         throw IOParameterError(msg.message());
    381       }
    382       node_readers.insert(make_pair(name, &node));
     227      node_reader.readNode(name, node);
    383228      return *this;
    384229    }
     
    388233    /// Add a new labeled edge reader for the reader.
    389234    GraphReader& readEdge(std::string name, Edge& edge) {
    390       if (edge_readers.find(name) != edge_readers.end()) {
    391         ErrorMessage msg;
    392         msg << "Multiple read rule for edge: " << name;
    393         throw IOParameterError(msg.message());
    394       }
    395       edge_readers.insert(make_pair(name, &edge));
    396       return *this;
     235      edge_reader.readEdge(name, edge);
     236    }
     237
     238    /// \brief Add a new attribute reader command.
     239    ///
     240    ///  Add a new attribute reader command.
     241    template <typename Value>
     242    GraphReader& readAttribute(std::string name, Value& value) {
     243      attribute_reader.readAttribute(name, value);
     244      return *this;
     245    }
     246   
     247    /// \brief Add a new attribute reader command.
     248    ///
     249    ///  Add a new attribute reader command.
     250    template <typename Reader, typename Value>
     251    GraphReader& readAttribute(std::string name, Value& value,
     252                               const Reader& reader) {
     253      attribute_reader.readAttribute<Reader>(name, value, reader);
     254      return *this;
     255    }
     256
     257    /// \brief Conversion operator to LemonReader.
     258    ///
     259    /// Conversion operator to LemonReader. It make possible
     260    /// to access the encapsulated \e LemonReader, this way
     261    /// you can attach to this reader new instances of
     262    /// \e LemonReader::SectionReader.
     263    operator LemonReader&() {
     264      return *reader;
    397265    }
    398266
     
    401269    /// Executes the reader commands.
    402270    void run() {
    403       int line_num = 0;
    404       std::auto_ptr<InverterBase<Node> > nodeInverter;
    405       std::auto_ptr<InverterBase<Edge> > edgeInverter;
    406       try {
    407         std::string line = readNotEmptyLine(is, line_num);
    408         if (line.find("@nodeset") == 0) {
    409           line = readNodeSet(line_num, nodeInverter);
    410         }
    411         if (line.find("@edgeset") == 0) {
    412           line = readEdgeSet(line_num, edgeInverter, nodeInverter);
    413         }
    414         if (line.find("@nodes") == 0) {
    415           line = readNodes(line_num, nodeInverter);
    416         }
    417         if (line.find("@edges") == 0) {
    418           line = readEdges(line_num, edgeInverter);
    419         }
    420         if (line.find("@gui") == 0) {
    421           line = readGUI(line_num);
    422         }
    423         if (line.find("@end") != 0) {
    424           throw DataFormatError("Invalid control sequence error");
    425         }
    426       } catch (DataFormatError e) {
    427         e.line(line_num);
    428         throw e;
    429       }
    430     }
    431 
    432     GraphReader& readGUI(GUIReader& reader) {
    433       gui_reader = &reader;
    434       return *this;
     271      reader->run();
    435272    }
    436273
    437274  private:
    438275
    439     template <typename Item> class InverterBase;
    440 
    441     std::string readNodeSet(int& line_num,
    442                             std::auto_ptr<InverterBase<Node> >& nodeInverter) {
    443       std::vector<ReaderBase<Node>* > index;
    444       {
    445         std::string line = readNotEmptyLine(is, line_num);   
    446         std::string id;
    447         std::istringstream ls(line);   
    448         while (ls >> id) {
    449           typename NodeMapReaders::iterator it = node_map_readers.find(id);
    450           if (it != node_map_readers.end()) {
    451             index.push_back(it->second);
    452             node_map_readers.erase(it);
    453           } else {
    454             index.push_back(&nodeSkipper);
    455           }
    456           if (ReaderTraits::idMapName(id) && nodeInverter.get() == 0) {
    457             nodeInverter.reset(index.back()->getInverter());
    458             index.back() = nodeInverter.get();
    459           }
    460         }
    461       }
    462 
    463 //       if (index.size() == 0) {
    464 //      throw DataFormatError("Cannot find node id map");
    465 //       }
    466 
    467 //       nodeInverter =
    468 //      std::auto_ptr<InverterBase<Node> >(index[0]->getInverter());
    469       std::string line;
    470       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
    471         Node node = graph.addNode();
    472         std::istringstream ls(line);
    473         for (int i = 0; i < (int)index.size(); ++i) {
    474           index[i]->read(ls, node);
    475         }
    476       }
    477       return line;
    478     }
    479 
    480     std::string readEdgeSet(int& line_num,
    481                             std::auto_ptr<InverterBase<Edge> >& edgeInverter,
    482                             std::auto_ptr<InverterBase<Node> >& nodeInverter) {
    483       std::vector<ReaderBase<Edge>*> index;
    484       {
    485         std::string line = readNotEmptyLine(is, line_num);   
    486         std::string id;
    487         std::istringstream ls(line);   
    488         while (ls >> id) {
    489           typename EdgeMapReaders::iterator it = edge_map_readers.find(id);
    490           if (it != edge_map_readers.end()) {
    491             index.push_back(it->second);
    492             edge_map_readers.erase(it);
    493           } else {
    494             index.push_back(&edgeSkipper);
    495           }
    496           if (ReaderTraits::idMapName(id) && edgeInverter.get() == 0) {
    497             edgeInverter.reset(index.back()->getInverter());
    498             index.back() = edgeInverter.get();
    499           }
    500         }
    501       }
    502      
    503       if (nodeInverter.get() == 0) {
    504         throw DataFormatError("Cannot find node id map");
    505       }
    506 //       if (index.size() == 0) {
    507 //      throw DataFormatError("Cannot find edge id map");
    508 //       }
    509 
    510 //       edgeInverter =
    511 //      std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
    512       std::string line;
    513       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {   
    514         std::istringstream ls(line);
    515         Node source = nodeInverter->read(ls);
    516         Node target = nodeInverter->read(ls);
    517         Edge edge = graph.addEdge(source, target);
    518         for (int i = 0; i < (int)index.size(); ++i) {
    519           index[i]->read(ls, edge);
    520         }
    521       }     
    522       return line;
    523     }
    524 
    525     std::string readNodes(int& line_num,
    526                           std::auto_ptr<InverterBase<Node> >& nodeInverter) {
    527       std::string line;
    528       if (nodeInverter.get() == 0) {
    529         throw DataFormatError("Cannot find node id map");
    530       }
    531       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
    532         std::istringstream ls(line);
    533         std::string name;
    534         ls >> name;
    535         typename NodeReaders::iterator it = node_readers.find(name);
    536         if (it != node_readers.end()) {
    537           *(it -> second) = nodeInverter->read(ls);
    538         }
    539       }       
    540       return line;
    541     }
    542 
    543     std::string readEdges(int& line_num,
    544                           std::auto_ptr<InverterBase<Edge> >& edgeInverter) {
    545       std::string line;
    546       if (edgeInverter.get() == 0) {
    547         throw DataFormatError("Cannot find edge id map");
    548       }
    549       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
    550         std::istringstream ls(line);
    551         std::string name;
    552         ls >> name;
    553         typename EdgeReaders::iterator it = edge_readers.find(name);
    554         if (it != edge_readers.end()) {
    555           *(it -> second) = edgeInverter->read(ls);
    556         }
    557       }       
    558       return line;   
    559     }
    560 
    561     std::string readGUI(int& line_num) {
    562       std::stringstream section;
    563       std::string line;
    564       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
    565         section << line << std::endl;
    566       }
    567       if (gui_reader != 0) {
    568         gui_reader->read(section);
    569       }
    570       return line;
    571     }
    572 
    573     std::string readNotEmptyLine(std::istream& is, int& line_num) {
    574       std::string line;
    575       while (++line_num, getline(is, line)) {   
    576         int vi = line.find('#');
    577         if (vi != (int)::std::string::npos) {
    578           line = line.substr(0, vi);
    579         }
    580         vi = line.find_first_not_of(" \t");
    581         if (vi != (int)std::string::npos) {
    582           return line.substr(vi);
    583         }
    584       }
    585       throw DataFormatError("End of stream error");
    586     }
     276    LemonReader* reader;
     277    bool own_reader;
     278
     279    Graph& graph;
     280
     281    DefaultSkipper skipper;
     282
     283    NodeSetReader<Graph, ReaderTraits> nodeset_reader;
     284    EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
     285
     286    NodeReader<Graph> node_reader;
     287    EdgeReader<Graph> edge_reader;
    587288   
    588     template <typename _Item>
    589     class ReaderBase;
    590    
    591     template <typename _Item>
    592     class InverterBase : public ReaderBase<_Item> {
    593     public:
    594       typedef _Item Item;
    595       virtual void read(std::istream&, const Item&) = 0;
    596       virtual Item read(std::istream&) = 0;
    597 
    598       virtual InverterBase<_Item>* getInverter() {
    599         return this;
    600       }
    601     };
    602 
    603     template <typename _Item, typename _Map, typename _Reader>
    604     class MapReaderInverter : public InverterBase<_Item> {
    605     public:
    606       typedef _Item Item;
    607       typedef _Reader Reader;
    608       typedef typename Reader::Value Value;
    609       typedef _Map Map;
    610       typedef std::map<Value, Item> Inverse;
    611 
    612       Map& map;
    613       Reader reader;
    614       Inverse inverse;
    615 
    616       MapReaderInverter(Map& _map, const Reader& _reader)
    617         : map(_map), reader(_reader) {}
    618 
    619       virtual ~MapReaderInverter() {}
    620 
    621       virtual void read(std::istream& is, const Item& item) {
    622         Value value;
    623         reader.read(is, value);
    624         map.set(item, value);
    625         typename Inverse::iterator it = inverse.find(value);
    626         if (it == inverse.end()) {
    627           inverse.insert(std::make_pair(value, item));
    628         } else {
    629           throw DataFormatError("Multiple ID occurence");
    630         }
    631       }
    632 
    633       virtual Item read(std::istream& is) {
    634         Value value;
    635         reader.read(is, value);
    636         typename Inverse::const_iterator it = inverse.find(value);
    637         if (it != inverse.end()) {
    638           return it->second;
    639         } else {
    640           throw DataFormatError("Invalid ID error");
    641         }
    642       }     
    643     };
    644 
    645     template <typename _Item, typename _Reader>
    646     class SkipReaderInverter : public InverterBase<_Item> {
    647     public:
    648       typedef _Item Item;
    649       typedef _Reader Reader;
    650       typedef typename Reader::Value Value;
    651       typedef std::map<Value, Item> Inverse;
    652 
    653       Reader reader;
    654 
    655       SkipReaderInverter(const Reader& _reader)
    656         : reader(_reader) {}
    657 
    658       virtual ~SkipReaderInverter() {}
    659 
    660       virtual void read(std::istream& is, const Item& item) {
    661         Value value;
    662         reader.read(is, value);
    663         typename Inverse::iterator it = inverse.find(value);
    664         if (it == inverse.end()) {
    665           inverse.insert(std::make_pair(value, item));
    666         } else {
    667           throw DataFormatError("Multiple ID occurence error");
    668         }
    669       }
    670 
    671       virtual Item read(std::istream& is) {
    672         Value value;
    673         reader.read(is, value);
    674         typename Inverse::const_iterator it = inverse.find(value);
    675         if (it != inverse.end()) {
    676           return it->second;
    677         } else {
    678           throw DataFormatError("Invalid ID error");
    679         }
    680       }     
    681     private:
    682       Inverse inverse;
    683     };
    684 
    685     // Readers
    686 
    687     template <typename _Item>   
    688     class ReaderBase {
    689     public:
    690       typedef _Item Item;
    691 
    692       //      virtual ~ReaderBase() {}
    693 
    694       virtual void read(std::istream& is, const Item& item) = 0;
    695       virtual InverterBase<_Item>* getInverter() = 0;
    696     };
    697 
    698     template <typename _Item, typename _Map, typename _Reader>
    699     class MapReader : public ReaderBase<_Item> {
    700     public:
    701       typedef _Map Map;
    702       typedef _Reader Reader;
    703       typedef typename Reader::Value Value;
    704       typedef _Item Item;
    705      
    706       Map& map;
    707       Reader reader;
    708 
    709       MapReader(Map& _map, const Reader& _reader)
    710         : map(_map), reader(_reader) {}
    711 
    712       virtual ~MapReader() {}
    713 
    714       virtual void read(std::istream& is, const Item& item) {
    715         Value value;
    716         reader.read(is, value);
    717         map.set(item, value);
    718       }
    719 
    720       virtual InverterBase<_Item>* getInverter() {
    721         return new MapReaderInverter<Item, Map, Reader>(map, reader);
    722       }
    723     };
    724 
    725 
    726     template <typename _Item, typename _Reader>
    727     class SkipReader : public ReaderBase<_Item> {
    728     public:
    729       typedef _Reader Reader;
    730       typedef typename Reader::Value Value;
    731       typedef _Item Item;
    732 
    733       Reader reader;
    734       SkipReader(const Reader& _reader) : reader(_reader) {}
    735 
    736       virtual ~SkipReader() {}
    737 
    738       virtual void read(std::istream& is, const Item&) {
    739         Value value;
    740         reader.read(is, value);
    741       }     
    742 
    743       virtual InverterBase<Item>* getInverter() {
    744         return new SkipReaderInverter<Item, Reader>(reader);
    745       }
    746     };
    747 
    748 
    749     typedef std::map<std::string, ReaderBase<Node>*> NodeMapReaders;
    750     NodeMapReaders node_map_readers;
    751 
    752     typedef std::map<std::string, ReaderBase<Edge>*> EdgeMapReaders;
    753     EdgeMapReaders edge_map_readers;
    754 
    755     typedef std::map<std::string, Node*> NodeReaders;
    756     NodeReaders node_readers;
    757 
    758     typedef std::map<std::string, Edge*> EdgeReaders;
    759     EdgeReaders edge_readers;
    760 
    761     GUIReader* gui_reader;
    762 
    763     std::istream& is;
    764     Graph& graph;
    765 
    766     SkipReader<Node, DefaultReader> nodeSkipper;
    767     SkipReader<Edge, DefaultReader> edgeSkipper;
    768 
     289    AttributeReader<ReaderTraits> attribute_reader;
    769290  };
    770291
Note: See TracChangeset for help on using the changeset viewer.