src/work/deba/graph_reader.h
author klao
Thu, 09 Dec 2004 15:30:12 +0000
changeset 1034 be6ee857b72d
child 1036 2f514b5c7122
permissions -rw-r--r--
Undir list and smart graph
     1 /* -*- C++ -*-
     2  * src/lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Combinatorial Optimization Research Group, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 ///\ingroup gio
    18 ///\file
    19 ///\brief Map utilities.
    20 
    21 #include <iostream>
    22 #include <sstream>
    23 
    24 #include <map>
    25 #include <vector>
    26 
    27 #include <lemon/error.h>
    28 
    29 /// \todo fix exceptions
    30 
    31 
    32 namespace lemon {
    33   
    34   struct DefaultReaderTraits {
    35 
    36     template <typename _Value>
    37     struct Reader {
    38       typedef _Value Value;
    39       void read(std::istream& is, Value& value) {
    40 	is >> value;
    41       }
    42     };
    43 
    44     template <typename _Value>
    45     struct Skipper {
    46       typedef _Value Value;
    47       void read(std::istream& is) {
    48 	Value tmp;
    49 	is >> tmp;
    50       }      
    51     };
    52 
    53     struct DefaultSkipper {
    54       void read(std::istream& is) {
    55 	std::string tmp;
    56 	is >> tmp;
    57       }
    58     };
    59   };
    60 
    61   class IOException {
    62     virtual string message() = 0;
    63   };
    64 
    65   class FileReaderException {
    66     virtual int getLine() = 0;    
    67   };
    68 
    69   
    70   
    71   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
    72   class GraphReader {
    73 
    74   public:
    75     
    76     typedef _Graph Graph;
    77     typedef typename Graph::Node Node;
    78     typedef typename Graph::Edge Edge;
    79 
    80     typedef _ReaderTraits ReaderTraits;
    81     
    82 
    83     GraphReader(std::istream& _is, Graph& _graph) : is(_is), graph(_graph) {}
    84 
    85     template <typename Map>
    86     GraphReader& readNodeMap(std::string name, Map& map, 
    87 			     const typename ReaderTraits::template Reader<typename Map::Value>& reader =
    88 			     typename ReaderTraits::template Reader<typename Map::Value>()) {
    89       return readNodeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader);
    90     }
    91 
    92     template <typename Map, typename Reader>
    93     GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) {
    94       node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
    95       return *this;
    96     }
    97 
    98     template <typename Map>
    99     GraphReader& readEdgeMap(std::string name, Map& map, 
   100 			     const typename ReaderTraits::template Reader<typename Map::Value>& reader =
   101 			     typename ReaderTraits::template Reader<typename Map::Value>()) {
   102       return readEdgeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader);
   103     }
   104 
   105     template <typename Map, typename Reader>
   106     GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) {
   107       edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   108       return *this;
   109     }
   110 
   111     void read() {
   112       int line_num = 0;
   113       readNodeSet(line_num);
   114       readEdgeSet(line_num);
   115       {
   116 	std::string line = readNotEmptyLine(is, line_num);
   117       }
   118     }
   119 
   120   private:
   121 
   122     void readNodeSet(int& line_num) {
   123       int n = 0;
   124       {
   125 	std::string line = readNotEmptyLine(is, line_num);	
   126       }
   127       std::vector<MapReaderBase<Node>*> index;
   128       {
   129 	std::string line = readNotEmptyLine(is, line_num);    
   130 	std::string id;
   131 	std::istringstream ls(line);	
   132 	while (ls >> id) {
   133 	  typename map<std::string, MapReaderBase<Node>* >::iterator it = node_readers.find(id);
   134 	  if (it != node_readers.end()) {
   135 	    index.push_back(it->second);
   136 	  } else {
   137 	    index.push_back(0);
   138 	  }
   139 	  ++n;
   140 	}
   141       }
   142       std::string line;
   143       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   144 	Node node = graph.addNode();
   145 	std::istringstream ls(line);
   146 	for (int i = 0; i < n; ++i) {
   147 	  if (index[i] != 0) {	    
   148 	    index[i]->read(ls, node);
   149 	  } else {
   150 	    default_skipper.read(ls);
   151 	  }
   152 	}
   153       }
   154     }
   155 
   156     void readEdgeSet(int& line_num) {
   157       
   158     }
   159 
   160     std::string readNotEmptyLine(std::istream& is, int& line_num) {
   161       std::string line;
   162       while (++line_num, getline(is, line)) {	
   163 	int vi = line.find_first_not_of(" \t");
   164 	if (vi != string::npos && line[vi] != '#') {
   165 	  return line.substr(vi);
   166 	}
   167       }
   168       throw Exception();
   169     }
   170     
   171     istream& is;
   172     Graph& graph;
   173 
   174     typename ReaderTraits::DefaultSkipper default_skipper;
   175 
   176     template <typename _Item>    
   177     class MapReaderBase {
   178     public:
   179       typedef _Item Item;
   180       virtual void read(istream& is, const Item& item) = 0;
   181     };
   182     
   183     template <typename _Item, typename _Map, typename _Reader>
   184     class MapReader : public MapReaderBase<_Item> {
   185     public:
   186       typedef _Map Map;
   187       typedef _Reader Reader;
   188       typedef _Item Item;
   189       
   190       Map& map;
   191       Reader reader;
   192 
   193       MapReader(Map& _map, const Reader& _reader) 
   194 	: map(_map), reader(_reader) {}
   195 
   196 
   197       virtual void read(istream& is, const Item& item) {
   198 	typename Reader::Value value;
   199 	reader.read(is, value);
   200 	map.set(item, value);
   201       }
   202     };
   203 
   204     typedef std::map<std::string, MapReaderBase<Node>* > NodeReaders;
   205     NodeReaders node_readers;
   206 
   207     typedef std::map<std::string, MapReaderBase<Edge>* > EdgeReaders;
   208     EdgeReaders edge_readers;
   209 
   210   };
   211 
   212 }