graph_io under construction
authordeba
Wed, 15 Dec 2004 19:56:55 +0000
changeset 10373eaff8d04171
parent 1036 2f514b5c7122
child 1038 ca63ec3424d8
graph_io under construction
This is a working version, but needs more improvments.

todo:
documention + fix the file format
improve the exception system

add some possible asserts

tutorials
src/work/deba/graph_io_test.cc
src/work/deba/graph_reader.h
src/work/deba/graph_writer.h
src/work/deba/map_utils.h
src/work/deba/test.lgf
     1.1 --- a/src/work/deba/graph_io_test.cc	Tue Dec 14 19:26:50 2004 +0000
     1.2 +++ b/src/work/deba/graph_io_test.cc	Wed Dec 15 19:56:55 2004 +0000
     1.3 @@ -1,5 +1,10 @@
     1.4  #include <lemon/smart_graph.h>
     1.5 +
     1.6 +#include "map_utils.h"
     1.7 +
     1.8 +
     1.9  #include "graph_reader.h"
    1.10 +#include "graph_writer.h"
    1.11  
    1.12  #include <iostream>
    1.13  #include <fstream>
    1.14 @@ -11,17 +16,30 @@
    1.15    ifstream input("test.lgf");
    1.16    SmartGraph graph;
    1.17    GraphReader<SmartGraph> reader(input, graph);
    1.18 +
    1.19    SmartGraph::NodeMap<int> id(graph);
    1.20    reader.readNodeMap("id", id);
    1.21 +
    1.22    SmartGraph::NodeMap<int> cost(graph);
    1.23    reader.readNodeMap("cost", cost);
    1.24 + 
    1.25    SmartGraph::NodeMap<string> color(graph);
    1.26    reader.readNodeMap("color", color);
    1.27 +
    1.28    SmartGraph::NodeMap<string> description(graph);
    1.29    reader.readNodeMap<QuotedStringReader>("description", description);
    1.30 +
    1.31    SmartGraph::EdgeMap<char> mmap(graph);
    1.32    reader.readEdgeMap("mmap", mmap);
    1.33 +
    1.34    reader.skipEdgeMap<QuotedStringReader>("description");
    1.35 +
    1.36 +  SmartGraph::Node source;
    1.37 +  reader.readNode("source", source);
    1.38 +  
    1.39 +  SmartGraph::Edge newedge;
    1.40 +  reader.readEdge("newedge", newedge);
    1.41 +
    1.42    try {
    1.43      reader.read();
    1.44    } catch (IOException& e) {
    1.45 @@ -36,5 +54,26 @@
    1.46    for (SmartGraph::EdgeIt it(graph); it != INVALID; ++it) {
    1.47      cout << mmap[it] << ' ' << id[graph.source(it)] << ' ' << id[graph.target(it)]  << endl;
    1.48    }
    1.49 +
    1.50 +  cout << id[source] << ' ' << cost[source] << ' ' << color[source] << ' ' << description[source] << endl;
    1.51 +  cout << mmap[newedge] << ' ' << id[graph.source(newedge)] << ' ' << id[graph.target(newedge)]  << endl;
    1.52 +
    1.53 +  ofstream output("copy.lgf");
    1.54 +  GraphWriter<SmartGraph> writer(output, graph);
    1.55 +  
    1.56 +  DescriptorMap<SmartGraph, SmartGraph::Node, SmartGraph::NodeIt, SmartGraph::NodeMap<int> > node_ids(graph);
    1.57 +  
    1.58 +  writer.writeNodeMap("id", node_ids);
    1.59 +  writer.writeNodeMap<QuotedStringWriter>("format", description);
    1.60 +
    1.61 +  DescriptorMap<SmartGraph, SmartGraph::Edge, SmartGraph::EdgeIt, SmartGraph::EdgeMap<int> > edge_ids(graph);
    1.62 +
    1.63 +  writer.writeEdgeMap("id", edge_ids);
    1.64 +  writer.writeEdgeMap("chars", mmap);
    1.65 +  
    1.66 +  writer.writeNode("source", node_ids.inverse()[3]);
    1.67 +  writer.writeEdge("elek", edge_ids.inverse()[6]);
    1.68 +  writer.write();
    1.69 +  
    1.70    return 0;
    1.71  }
     2.1 --- a/src/work/deba/graph_reader.h	Tue Dec 14 19:26:50 2004 +0000
     2.2 +++ b/src/work/deba/graph_reader.h	Wed Dec 15 19:56:55 2004 +0000
     2.3 @@ -24,6 +24,8 @@
     2.4  #include <map>
     2.5  #include <vector>
     2.6  
     2.7 +#include <memory>
     2.8 +
     2.9  #include <lemon/error.h>
    2.10  
    2.11  /// \todo fix exceptions
    2.12 @@ -48,11 +50,21 @@
    2.13      }
    2.14    };
    2.15  
    2.16 -  class StreamException : public IOException {
    2.17 +  template <typename _Exception>
    2.18 +  class StreamException : public _Exception {
    2.19    public:
    2.20 -    virtual int line() = 0;
    2.21 +    typedef _Exception Exception;
    2.22 +    StreamException(int _line, Exception _exception) 
    2.23 +      : line_num(_line), Exception(_exception) {}
    2.24 +    virtual int line() const {
    2.25 +      return line_num;
    2.26 +    }
    2.27 +    virtual std::string what() const {
    2.28 +      ostringstream os;
    2.29 +      os << Exception::what() << " in line " << line();
    2.30 +      return os.str();
    2.31 +    }
    2.32    private:
    2.33 -    IOException* exception;
    2.34      int line_num;
    2.35    };  
    2.36  
    2.37 @@ -84,7 +96,7 @@
    2.38        char c;
    2.39        value.clear();
    2.40        is >> ws;
    2.41 -      if (!is.get(c) || c != '\"') throw DataFormatException("Quoted string format exception");
    2.42 +      if (!is.get(c) || c != '\"') throw DataFormatException("Quoted string format");
    2.43        while (is.get(c) && c != '\"') {
    2.44  	if (escaped && c == '\\') {
    2.45  	  value += readEscape(is);
    2.46 @@ -92,7 +104,7 @@
    2.47  	  value += c;
    2.48  	}
    2.49        }
    2.50 -      if (!is) throw DataFormatException("Quoted string format exception");
    2.51 +      if (!is) throw DataFormatException("Quoted string format");
    2.52      }
    2.53  
    2.54    private:
    2.55 @@ -171,7 +183,6 @@
    2.56    
    2.57    template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
    2.58    class GraphReader {
    2.59 -
    2.60    public:
    2.61      
    2.62      typedef _Graph Graph;
    2.63 @@ -181,22 +192,24 @@
    2.64      typedef _ReaderTraits ReaderTraits;
    2.65      typedef typename ReaderTraits::DefaultReader DefaultReader;
    2.66  
    2.67 -    GraphReader(istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader()) 
    2.68 +    GraphReader(std::istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader()) 
    2.69        : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {}
    2.70  
    2.71  
    2.72      ~GraphReader() {
    2.73  
    2.74 -      for (typename NodeReaders::iterator it = node_readers.begin(); it != node_readers.end(); ++it) {
    2.75 +      for (typename NodeMapReaders::iterator it = node_map_readers.begin(); it != node_map_readers.end(); ++it) {
    2.76  	delete it->second;
    2.77        }
    2.78  
    2.79 -      for (typename EdgeReaders::iterator it = edge_readers.begin(); it != edge_readers.end(); ++it) {
    2.80 +      for (typename EdgeMapReaders::iterator it = edge_map_readers.begin(); it != edge_map_readers.end(); ++it) {
    2.81  	delete it->second;
    2.82        }
    2.83  
    2.84      }
    2.85  
    2.86 +    // Node map rules
    2.87 +
    2.88      template <typename Map>
    2.89      GraphReader& readNodeMap(std::string name, Map& map) {
    2.90        return readNodeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map);
    2.91 @@ -204,26 +217,24 @@
    2.92  
    2.93      template <typename Reader, typename Map>
    2.94      GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) {
    2.95 -      if (node_readers.find(name) != node_readers.end()) {
    2.96 -	Exception e;
    2.97 -	e << "Multiple read rule for node map: " << name;
    2.98 -	throw e;
    2.99 +      if (node_map_readers.find(name) != node_map_readers.end()) {
   2.100 +	throw Exception() << "Multiple read rule for node map: " << name;
   2.101        }
   2.102 -      node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
   2.103 +      node_map_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
   2.104        return *this;
   2.105      }
   2.106  
   2.107      template <typename Reader>
   2.108      GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) {
   2.109 -      if (node_readers.find(name) != node_readers.end()) {
   2.110 -	Exception e;
   2.111 -	e << "Multiple read rule for node map: " << name;
   2.112 -	throw e;
   2.113 +      if (node_map_readers.find(name) != node_map_readers.end()) {
   2.114 +	throw Exception() << "Multiple read rule for node map: " << name;
   2.115        }
   2.116 -      node_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
   2.117 +      node_map_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
   2.118        return *this;
   2.119      }
   2.120  
   2.121 +    // Edge map rules
   2.122 +
   2.123      template <typename Map>
   2.124      GraphReader& readEdgeMap(std::string name, Map& map) { 
   2.125        return readEdgeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map);
   2.126 @@ -232,81 +243,106 @@
   2.127  
   2.128      template <typename Reader, typename Map>
   2.129      GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) {
   2.130 -      if (edge_readers.find(name) != edge_readers.end()) {
   2.131 -	Exception e;
   2.132 -	e << "Multiple read rule for edge map: " << name;
   2.133 -	throw e;
   2.134 +      if (edge_map_readers.find(name) != edge_map_readers.end()) {
   2.135 +	throw Exception() << "Multiple read rule for edge map: " << name;
   2.136        }
   2.137 -      edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   2.138 +      edge_map_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   2.139        return *this;
   2.140      }
   2.141  
   2.142      template <typename Reader>
   2.143      GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) {
   2.144 +      if (edge_map_readers.find(name) != edge_map_readers.end()) {
   2.145 +	throw Exception() << "Multiple read rule for edge map: " << name;
   2.146 +      }
   2.147 +      edge_map_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
   2.148 +      return *this;
   2.149 +    }
   2.150 +
   2.151 +    // Node rules
   2.152 +    GraphReader& readNode(std::string name, Node& node) {
   2.153 +      if (node_readers.find(name) != node_readers.end()) {
   2.154 +	throw Exception() << "Multiple read rule for node";
   2.155 +      }
   2.156 +      node_readers.insert(make_pair(name, &node));
   2.157 +    }
   2.158 +
   2.159 +    // Edge rules
   2.160 +
   2.161 +    GraphReader& readEdge(std::string name, Edge& edge) {
   2.162        if (edge_readers.find(name) != edge_readers.end()) {
   2.163 -	Exception e;
   2.164 -	e << "Multiple read rule for edge map: " << name;
   2.165 -	throw e;
   2.166 +	throw Exception() << "Multiple read rule for edge";
   2.167        }
   2.168 -      edge_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
   2.169 -      return *this;
   2.170 +      edge_readers.insert(make_pair(name, &edge));
   2.171      }
   2.172  
   2.173      void read() {
   2.174        int line_num = 0;
   2.175 -      InverterBase<Node>* nodeInverter = 0;
   2.176 -      InverterBase<Edge>* edgeInverter = 0;
   2.177 -      // \todo delete the inverters
   2.178 -      //      try {
   2.179 -	{
   2.180 -	  std::string line = readNotEmptyLine(is, line_num);
   2.181 +      std::auto_ptr<InverterBase<Node> > nodeInverter;
   2.182 +      std::auto_ptr<InverterBase<Edge> > edgeInverter;
   2.183 +      try {
   2.184 +	std::string line = readNotEmptyLine(is, line_num);
   2.185 +	if (line.find("@nodeset") == 0) {
   2.186 +	  line = readNodeSet(line_num, nodeInverter);
   2.187 +	} 
   2.188 +	if (line.find("@edgeset") == 0) {
   2.189 +	  line = readEdgeSet(line_num, edgeInverter, nodeInverter);
   2.190  	}
   2.191 -	readNodeSet(line_num, nodeInverter);
   2.192 -	readEdgeSet(line_num, edgeInverter, nodeInverter);
   2.193 -	//      } catch (...){
   2.194 -	if (nodeInverter != 0) delete nodeInverter;
   2.195 -	if (edgeInverter != 0) delete edgeInverter;
   2.196 -	//      }
   2.197 +	if (line.find("@nodes") == 0) {
   2.198 +	  line = readNodes(line_num, nodeInverter);
   2.199 +	}
   2.200 +	if (line.find("@edges") == 0) {
   2.201 +	  line = readEdges(line_num, edgeInverter);
   2.202 +	}
   2.203 +	if (line.find("@end") != 0) {
   2.204 +	  throw DataFormatException("Invalid control sequence: " + line);
   2.205 +	}
   2.206 +      } catch (DataFormatException e) {
   2.207 +	throw StreamException<DataFormatException>(line_num, e);
   2.208 +      }
   2.209      }
   2.210  
   2.211    private:
   2.212  
   2.213      template <typename Item> class InverterBase;
   2.214 -    //    template <typename Item> class InverterBase;
   2.215  
   2.216 -    void readNodeSet(int& line_num, InverterBase<Node>* & nodeInverter) {
   2.217 -      int n = 0;
   2.218 -      std::vector<ReaderBase<Node>*> index;
   2.219 +    std::string readNodeSet(int& line_num, auto_ptr<InverterBase<Node> > & nodeInverter) {
   2.220 +      std::vector<ReaderBase<Node>* > index;
   2.221        {
   2.222  	std::string line = readNotEmptyLine(is, line_num);    
   2.223  	std::string id;
   2.224  	std::istringstream ls(line);	
   2.225  	while (ls >> id) {
   2.226  	  if (id[0] == '#') break;
   2.227 -	  typename NodeReaders::iterator it = node_readers.find(id);
   2.228 -	  if (it != node_readers.end()) {
   2.229 +	  typename NodeMapReaders::iterator it = node_map_readers.find(id);
   2.230 +	  if (it != node_map_readers.end()) {
   2.231  	    index.push_back(it->second);
   2.232 +	    node_map_readers.erase(it);
   2.233  	  } else {
   2.234  	    index.push_back(&nodeSkipper);
   2.235  	  }
   2.236 -	  ++n;
   2.237  	}
   2.238        }
   2.239  
   2.240 -      nodeInverter = index[0]->getInverter();
   2.241 +      if (index.size() == 0) {
   2.242 +	throw DataFormatException("No node map found");
   2.243 +      }
   2.244 +
   2.245 +      nodeInverter = auto_ptr<InverterBase<Node> >(index[0]->getInverter());
   2.246        std::string line;
   2.247        while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   2.248  	Node node = graph.addNode();
   2.249  	std::istringstream ls(line);
   2.250  	nodeInverter->read(ls, node);
   2.251 -	for (int i = 1; i < n; ++i) {
   2.252 +	for (int i = 1; i < index.size(); ++i) {
   2.253  	  index[i]->read(ls, node);
   2.254  	}
   2.255        }
   2.256 +      return line;
   2.257      }
   2.258  
   2.259 -    void readEdgeSet(int& line_num, InverterBase<Edge>* & edgeInverter, InverterBase<Node>* & nodeInverter) {
   2.260 -      int n = 0;
   2.261 +    std::string readEdgeSet(int& line_num, 
   2.262 +		     auto_ptr<InverterBase<Edge> > & edgeInverter, auto_ptr<InverterBase<Node> > & nodeInverter) {
   2.263        std::vector<ReaderBase<Edge>*> index;
   2.264        {
   2.265  	std::string line = readNotEmptyLine(is, line_num);    
   2.266 @@ -314,16 +350,21 @@
   2.267  	std::istringstream ls(line);	
   2.268  	while (ls >> id) {
   2.269  	  if (id[0] == '#') break;
   2.270 -	  typename EdgeReaders::iterator it = edge_readers.find(id);
   2.271 -	  if (it != edge_readers.end()) {
   2.272 +	  typename EdgeMapReaders::iterator it = edge_map_readers.find(id);
   2.273 +	  if (it != edge_map_readers.end()) {
   2.274  	    index.push_back(it->second);
   2.275 +	    edge_map_readers.erase(it);
   2.276  	  } else {
   2.277  	    index.push_back(&edgeSkipper);
   2.278  	  }
   2.279 -	  ++n;
   2.280  	}
   2.281        }
   2.282 -      edgeInverter = index[0]->getInverter();
   2.283 +
   2.284 +      if (index.size() == 0) {
   2.285 +	throw DataFormatException("No edge map found");
   2.286 +      }
   2.287 +
   2.288 +      edgeInverter = auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
   2.289        std::string line;
   2.290        while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	
   2.291  	std::istringstream ls(line);
   2.292 @@ -331,10 +372,39 @@
   2.293  	Node target = nodeInverter->read(ls);
   2.294  	Edge edge = graph.addEdge(source, target);
   2.295  	edgeInverter->read(ls, edge);
   2.296 -	for (int i = 1; i < n; ++i) {
   2.297 +	for (int i = 1; i < index.size(); ++i) {
   2.298  	  index[i]->read(ls, edge);
   2.299  	}
   2.300        }      
   2.301 +      return line;
   2.302 +    }
   2.303 +
   2.304 +    std::string readNodes(int& line_num, auto_ptr<InverterBase<Node> >& nodeInverter) {
   2.305 +      std::string line;
   2.306 +      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   2.307 +	std::istringstream ls(line);
   2.308 +	std::string name;
   2.309 +	ls >> name;
   2.310 +	typename NodeReaders::iterator it = node_readers.find(name);
   2.311 +	if (it != node_readers.end()) {
   2.312 +	  *(it -> second) = nodeInverter->read(ls);
   2.313 +	} 
   2.314 +      }        
   2.315 +      return line;
   2.316 +    }
   2.317 +
   2.318 +    std::string readEdges(int& line_num, auto_ptr<InverterBase<Edge> >& edgeInverter) {
   2.319 +      std::string line;
   2.320 +      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   2.321 +	std::istringstream ls(line);
   2.322 +	std::string name;
   2.323 +	ls >> name;
   2.324 +	typename EdgeReaders::iterator it = edge_readers.find(name);
   2.325 +	if (it != edge_readers.end()) {
   2.326 +	  *(it -> second) = edgeInverter->read(ls);
   2.327 +	} 
   2.328 +      }        
   2.329 +      return line;    
   2.330      }
   2.331  
   2.332      std::string readNotEmptyLine(std::istream& is, int& line_num) {
   2.333 @@ -345,15 +415,18 @@
   2.334  	  return line.substr(vi);
   2.335  	}
   2.336        }
   2.337 -      throw Exception();
   2.338 +      throw DataFormatException("End of stream");
   2.339      }
   2.340      
   2.341 +    // Inverters store and give back the Item from the id,
   2.342 +    // and may put the ids into a map.
   2.343 +    
   2.344      template <typename _Item>
   2.345      class InverterBase {
   2.346      public:
   2.347        typedef _Item Item;
   2.348 -      virtual void read(istream&, const Item&) = 0;
   2.349 -      virtual Item read(istream&) = 0;
   2.350 +      virtual void read(std::istream&, const Item&) = 0;
   2.351 +      virtual Item read(std::istream&) = 0;
   2.352      };
   2.353  
   2.354      template <typename _Item, typename _Map, typename _Reader>
   2.355 @@ -372,7 +445,7 @@
   2.356        MapReaderInverter(Map& _map, const Reader& _reader) 
   2.357  	: map(_map), reader(_reader) {}
   2.358  
   2.359 -      virtual void read(istream& is, const Item& item) {
   2.360 +      virtual void read(std::istream& is, const Item& item) {
   2.361  	Value value;
   2.362  	reader.read(is, value);
   2.363  	map.set(item, value);
   2.364 @@ -384,7 +457,7 @@
   2.365  	}
   2.366        }
   2.367  
   2.368 -      virtual Item read(istream& is) {
   2.369 +      virtual Item read(std::istream& is) {
   2.370  	Value value;
   2.371  	reader.read(is, value);	
   2.372  	typename Inverse::const_iterator it = inverse.find(value);
   2.373 @@ -409,7 +482,7 @@
   2.374        SkipReaderInverter(const Reader& _reader) 
   2.375  	: reader(_reader) {}
   2.376  
   2.377 -      virtual void read(istream& is, const Item& item) {
   2.378 +      virtual void read(std::istream& is, const Item& item) {
   2.379  	Value value;
   2.380  	reader.read(is, value);
   2.381  	typename Inverse::iterator it = inverse.find(value);
   2.382 @@ -420,7 +493,7 @@
   2.383  	}
   2.384        }
   2.385  
   2.386 -      virtual Item read(istream& is) {
   2.387 +      virtual Item read(std::istream& is) {
   2.388  	Value value;
   2.389  	reader.read(is, value);	
   2.390  	typename Inverse::const_iterator it = inverse.find(value);
   2.391 @@ -434,12 +507,14 @@
   2.392        Inverse inverse;
   2.393      };
   2.394  
   2.395 +    // Readers
   2.396  
   2.397      template <typename _Item>    
   2.398      class ReaderBase {
   2.399      public:
   2.400        typedef _Item Item;
   2.401 -      virtual void read(istream& is, const Item& item) = 0;
   2.402 +
   2.403 +      virtual void read(std::istream& is, const Item& item) = 0;
   2.404        virtual InverterBase<_Item>* getInverter() = 0;
   2.405      };
   2.406  
   2.407 @@ -458,7 +533,7 @@
   2.408  	: map(_map), reader(_reader) {}
   2.409  
   2.410  
   2.411 -      virtual void read(istream& is, const Item& item) {
   2.412 +      virtual void read(std::istream& is, const Item& item) {
   2.413  	Value value;
   2.414  	reader.read(is, value);
   2.415  	map.set(item, value);
   2.416 @@ -480,7 +555,7 @@
   2.417        Reader reader;
   2.418        SkipReader(const Reader& _reader) : reader(_reader) {}
   2.419  
   2.420 -      virtual void read(istream& is, const Item& item) {
   2.421 +      virtual void read(std::istream& is, const Item& item) {
   2.422  	Value value;
   2.423  	reader.read(is, value);
   2.424        }      
   2.425 @@ -491,10 +566,16 @@
   2.426      };
   2.427  
   2.428  
   2.429 -    typedef std::map<std::string, ReaderBase<Node>* > NodeReaders;
   2.430 +    typedef std::map<std::string, ReaderBase<Node>*> NodeMapReaders;
   2.431 +    NodeMapReaders node_map_readers;
   2.432 +
   2.433 +    typedef std::map<std::string, ReaderBase<Edge>*> EdgeMapReaders;
   2.434 +    EdgeMapReaders edge_map_readers;
   2.435 +
   2.436 +    typedef std::map<std::string, Node*> NodeReaders;
   2.437      NodeReaders node_readers;
   2.438  
   2.439 -    typedef std::map<std::string, ReaderBase<Edge>* > EdgeReaders;
   2.440 +    typedef std::map<std::string, Edge*> EdgeReaders;
   2.441      EdgeReaders edge_readers;
   2.442  
   2.443      std::istream& is;
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/work/deba/graph_writer.h	Wed Dec 15 19:56:55 2004 +0000
     3.3 @@ -0,0 +1,324 @@
     3.4 +/* -*- C++ -*-
     3.5 + * src/lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library
     3.6 + *
     3.7 + * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     3.8 + * (Egervary Combinatorial Optimization Research Group, EGRES).
     3.9 + *
    3.10 + * Permission to use, modify and distribute this software is granted
    3.11 + * provided that this copyright notice appears in all copies. For
    3.12 + * precise terms see the accompanying LICENSE file.
    3.13 + *
    3.14 + * This software is provided "AS IS" with no warranty of any kind,
    3.15 + * express or implied, and with no claim as to its suitability for any
    3.16 + * purpose.
    3.17 + *
    3.18 + */
    3.19 +
    3.20 +///\ingroup gio
    3.21 +///\file
    3.22 +///\brief Graph writer.
    3.23 +
    3.24 +
    3.25 +#include <iostream>
    3.26 +#include <sstream>
    3.27 +
    3.28 +#include <map>
    3.29 +#include <vector>
    3.30 +
    3.31 +#include <memory>
    3.32 +
    3.33 +#include <lemon/invalid.h>
    3.34 +#include <lemon/error.h>
    3.35 +
    3.36 +
    3.37 +namespace lemon {
    3.38 +
    3.39 +  struct DefaultWriterTraits {
    3.40 +
    3.41 +    template <typename _Value>
    3.42 +    struct Writer {
    3.43 +      typedef _Value Value;
    3.44 +
    3.45 +      void write(std::ostream& os, const Value& value) {
    3.46 +	os << value << '\t';
    3.47 +      }
    3.48 +    };
    3.49 +
    3.50 +  };
    3.51 +
    3.52 +
    3.53 +  class QuotedStringWriter {
    3.54 +  public:
    3.55 +    typedef std::string Value;
    3.56 +
    3.57 +    QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
    3.58 +
    3.59 +    void write(std::ostream& os, const std::string& value) {
    3.60 +      char c;
    3.61 +      os << "\"";
    3.62 +      if (escaped) {
    3.63 +	ostringstream ls;
    3.64 +	for (int i = 0; i < value.size(); ++i) {
    3.65 +	  writeEscape(ls, value[i]);
    3.66 +	}
    3.67 +	os << ls.str();
    3.68 +      } else {
    3.69 +	os << value;
    3.70 +      }
    3.71 +      os << "\"";
    3.72 +    }
    3.73 +
    3.74 +  private:
    3.75 +    
    3.76 +    static void writeEscape(std::ostream& os, char c) {
    3.77 +      switch (c) {
    3.78 +      case '\\':
    3.79 +	os << "\\\\";
    3.80 +	return;
    3.81 +      case '\"':
    3.82 +	os << "\\\"";
    3.83 +	return;
    3.84 +      case '\'':
    3.85 +	os << "\\\'";
    3.86 +	return;
    3.87 +      case '\?':
    3.88 +	os << "\\\?";
    3.89 +	return;
    3.90 +      case '\a':
    3.91 +	os << "\\a";
    3.92 +	return;
    3.93 +      case '\b':
    3.94 +	os << "\\b";
    3.95 +	return;
    3.96 +      case '\f':
    3.97 +	os << "\\f";
    3.98 +	return;
    3.99 +      case '\r':
   3.100 +	os << "\\r";
   3.101 +	return;
   3.102 +      case '\n':
   3.103 +	os << "\\n";
   3.104 +	return;
   3.105 +      case '\t':
   3.106 +	os << "\\t";
   3.107 +	return;
   3.108 +      case '\v':
   3.109 +	os << "\\v";
   3.110 +	return;
   3.111 +      default:
   3.112 +	if (c < 0x20) {
   3.113 +	  os << '\\' << oct << (int)c;
   3.114 +	} else {
   3.115 +	  os << c;
   3.116 +	}
   3.117 +	return;
   3.118 +      }     
   3.119 +    }
   3.120 +  private:
   3.121 +    bool escaped;
   3.122 +  };
   3.123 +
   3.124 +  // Graph writer
   3.125 +  
   3.126 +  template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   3.127 +  class GraphWriter {
   3.128 +  public:
   3.129 +    
   3.130 +    typedef _Graph Graph;
   3.131 +    typedef typename Graph::Node Node;
   3.132 +    typedef typename Graph::NodeIt NodeIt;
   3.133 +    typedef typename Graph::Edge Edge;
   3.134 +    typedef typename Graph::EdgeIt EdgeIt;
   3.135 +
   3.136 +    typedef _WriterTraits WriterTraits;
   3.137 +
   3.138 +    GraphWriter(std::ostream& _os, Graph& _graph) : os(_os), graph(_graph) {}
   3.139 +
   3.140 +
   3.141 +    ~GraphWriter() {
   3.142 +
   3.143 +      for (typename NodeMapWriters::iterator it = node_map_writers.begin(); it != node_map_writers.end(); ++it) {
   3.144 +	delete it->second;
   3.145 +      }
   3.146 +
   3.147 +      for (typename EdgeMapWriters::iterator it = edge_map_writers.begin(); it != edge_map_writers.end(); ++it) {
   3.148 +	delete it->second;
   3.149 +      }
   3.150 +
   3.151 +    }
   3.152 +
   3.153 +    // Node map rules
   3.154 +
   3.155 +    template <typename Map>
   3.156 +    GraphWriter& writeNodeMap(std::string name, const Map& map) {
   3.157 +      return writeNodeMap<typename WriterTraits::template Writer<typename Map::Value>, Map>(name, map);
   3.158 +    }
   3.159 +
   3.160 +    template <typename Writer, typename Map>
   3.161 +    GraphWriter& writeNodeMap(std::string name, const Map& map, const Writer& writer = Writer()) {
   3.162 +      //      if (node_map_writers.find(name) != node_map_writers.end()) {
   3.163 +      //	throw Exception() << "Multiple write rule for node map: " << name;
   3.164 +      //      }
   3.165 +      node_map_writers.push_back(make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
   3.166 +      return *this;
   3.167 +    }
   3.168 +
   3.169 +    // Edge map rules
   3.170 +
   3.171 +    template <typename Map>
   3.172 +    GraphWriter& writeEdgeMap(std::string name, const Map& map) { 
   3.173 +      return writeEdgeMap<typename WriterTraits::template Writer<typename Map::Value>, Map>(name, map);
   3.174 +    }
   3.175 +
   3.176 +
   3.177 +    template <typename Writer, typename Map>
   3.178 +    GraphWriter& writeEdgeMap(std::string name, const Map& map, const Writer& writer = Writer()) {
   3.179 +      //      if (edge_map_writers.find(name) != edge_map_writers.end()) {
   3.180 +      //	throw Exception() << "Multiple write rule for edge map: " << name;
   3.181 +      //      }
   3.182 +      edge_map_writers.push_back(make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
   3.183 +      return *this;
   3.184 +    }
   3.185 +
   3.186 +    // Node rules
   3.187 +    GraphWriter& writeNode(std::string name, const Node& node) {
   3.188 +      //      if (node_writers.find(name) != node_writers.end()) {
   3.189 +      //	throw Exception() << "Multiple write rule for node";
   3.190 +      //      }
   3.191 +      node_writers.push_back(make_pair(name, node));
   3.192 +    }
   3.193 +
   3.194 +    // Edge rules
   3.195 +
   3.196 +    GraphWriter& writeEdge(std::string name, const Edge& edge) {
   3.197 +      //      if (edge_writers.find(name) != edge_writers.end()) {
   3.198 +      //	throw Exception() << "Multiple write rule for edge";
   3.199 +      //      }
   3.200 +      edge_writers.push_back(make_pair(name, edge));
   3.201 +    }
   3.202 +
   3.203 +    void write() {   
   3.204 +      writeNodeSet();
   3.205 +      writeEdgeSet();
   3.206 +      writeNodes();
   3.207 +      writeEdges();
   3.208 +      os << "@end" << std::endl;
   3.209 +    }
   3.210 +
   3.211 +  private:
   3.212 +
   3.213 +    void writeNodeSet() {
   3.214 +      if (node_map_writers.size() == 0) return;
   3.215 +      os << "@nodeset" << std::endl;
   3.216 +      for (int i = 0; i < node_map_writers.size(); ++i) {
   3.217 +	os << node_map_writers[i].first << '\t';
   3.218 +      } 
   3.219 +      os << std::endl;
   3.220 +      for (NodeIt it(graph); it != INVALID; ++it) {
   3.221 +	for (int i = 0; i < node_map_writers.size(); ++i) {
   3.222 +	  node_map_writers[i].second->write(os, it);
   3.223 +	}
   3.224 +	os << std::endl;
   3.225 +      }
   3.226 +
   3.227 +    }
   3.228 +
   3.229 +    void writeEdgeSet() {
   3.230 +      if (edge_map_writers.size() == 0) return;
   3.231 +      if (node_map_writers.size() == 0) {
   3.232 +	throw Exception() << "Missing node id map";
   3.233 +      }
   3.234 +      os << "@edgeset" << std::endl;
   3.235 +      os << "\t\t";
   3.236 +      for (int i = 0; i < edge_map_writers.size(); ++i) {
   3.237 +	os << edge_map_writers[i].first << '\t';
   3.238 +      } 
   3.239 +      os << std::endl;
   3.240 +      for (EdgeIt it(graph); it != INVALID; ++it) {
   3.241 +	node_map_writers[0].second->write(os, graph.source(it));
   3.242 +	node_map_writers[0].second->write(os, graph.target(it));
   3.243 +	for (int i = 0; i < edge_map_writers.size(); ++i) {
   3.244 +	  edge_map_writers[i].second->write(os, it);
   3.245 +	}
   3.246 +	os << std::endl;
   3.247 +      }
   3.248 +    }
   3.249 +
   3.250 +    void writeNodes() {
   3.251 +      if (node_writers.size() == 0) return;
   3.252 +      if (node_map_writers.size() == 0) {
   3.253 +	throw Exception() << "Missing node id map";
   3.254 +      }
   3.255 +      os << "@nodes" << std::endl;
   3.256 +      for (int i = 0; i < node_writers.size(); ++i) {
   3.257 +	os << node_writers[i].first << '\t';
   3.258 +	node_map_writers[0].second->write(os, node_writers[i].second);
   3.259 +	os << std::endl;
   3.260 +      } 
   3.261 +    }
   3.262 +
   3.263 +    void writeEdges() {
   3.264 +      if (edge_writers.size() == 0) return;
   3.265 +      if (edge_map_writers.size() == 0) {
   3.266 +	throw Exception() << "Missing edge id map";
   3.267 +      }
   3.268 +      os << "@edges" << std::endl;
   3.269 +      for (int i = 0; i < edge_writers.size(); ++i) {
   3.270 +	os << edge_writers[i].first << '\t';
   3.271 +	edge_map_writers[0].second->write(os, edge_writers[i].second);
   3.272 +	os << std::endl;
   3.273 +      } 
   3.274 +    }
   3.275 +    
   3.276 +    // Writers
   3.277 +
   3.278 +    template <class _Item>
   3.279 +    class WriterBase {
   3.280 +    public:
   3.281 +      typedef _Item Item;
   3.282 +      virtual void write(std::ostream&, const Item&) = 0;
   3.283 +    };
   3.284 +
   3.285 +    template <class _Item, typename _Map, typename _Writer>
   3.286 +    class MapWriter : public WriterBase<_Item> {
   3.287 +    public:
   3.288 +      typedef _Map Map;
   3.289 +      typedef _Writer Writer;
   3.290 +      typedef typename Writer::Value Value;
   3.291 +      typedef _Item Item;
   3.292 +      
   3.293 +      const Map& map;
   3.294 +      Writer writer;
   3.295 +
   3.296 +      MapWriter(const Map& _map, const Writer& _writer) 
   3.297 +	: map(_map), writer(_writer) {}
   3.298 +
   3.299 +
   3.300 +      virtual void write(std::ostream& os, const Item& item) {
   3.301 +	Value value;
   3.302 +	writer.write(os, map[item]);
   3.303 +      }
   3.304 +
   3.305 +    };
   3.306 +
   3.307 +
   3.308 +
   3.309 +    typedef std::vector< std::pair<std::string, WriterBase<Node>*> > NodeMapWriters;
   3.310 +    NodeMapWriters node_map_writers;
   3.311 +
   3.312 +    typedef std::vector< std::pair<std::string, WriterBase<Edge>*> > EdgeMapWriters;
   3.313 +    EdgeMapWriters edge_map_writers;
   3.314 +
   3.315 +    typedef std::vector<std::pair<std::string, Node> > NodeWriters;
   3.316 +    NodeWriters node_writers;
   3.317 +
   3.318 +    typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
   3.319 +    EdgeWriters edge_writers;
   3.320 +
   3.321 +    std::ostream& os;
   3.322 +    Graph& graph;
   3.323 +
   3.324 +  };
   3.325 +
   3.326 +
   3.327 +}
     4.1 --- a/src/work/deba/map_utils.h	Tue Dec 14 19:26:50 2004 +0000
     4.2 +++ b/src/work/deba/map_utils.h	Wed Dec 15 19:56:55 2004 +0000
     4.3 @@ -35,19 +35,19 @@
     4.4    /// in the inverse map.
     4.5    template <
     4.6      typename _Graph, 
     4.7 -    typename _Map, 
     4.8 -    template <typename, typename> class _InvMap = std::Map
     4.9 +    typename _Map
    4.10    >
    4.11    class InversableMap : protected _Map {
    4.12  
    4.13    public:
    4.14 +    typedef _Graph Graph;
    4.15  
    4.16 -    typename _Map Map;
    4.17 -    typename _InvMap<Map::Value, Map::Key> InverseMap;
    4.18 +    typedef _Map Map;
    4.19 +    typedef typename _Map::Key Key;
    4.20 +    typedef typename _Map::Value Value;
    4.21 +    typedef std::map<Value, Key> InverseMap;
    4.22      
    4.23 -    typename _Map::Key Key;
    4.24 -    typename _Map::Value Value;
    4.25 -    typename _Map::ConstReference ConstReference;
    4.26 +    typedef typename _Map::ConstReference ConstReference;
    4.27  
    4.28      /// Constructor.
    4.29  
    4.30 @@ -60,11 +60,11 @@
    4.31      /// It sets the map and the inverse map 
    4.32      void set(const Key& key, const Value& val) {
    4.33        Value oldval = Map::operator[](key);
    4.34 -      InverseMap::iterator it = invMap.find(oldval);
    4.35 -      if (it != invMap.end() && it->second == key) {
    4.36 -	invMap.erase(it);
    4.37 +      typename InverseMap::iterator it = inv_map.find(oldval);
    4.38 +      if (it != inv_map.end() && it->second == key) {
    4.39 +	inv_map.erase(it);
    4.40        }      
    4.41 -      invMap.insert(make_pair(val, key));
    4.42 +      inv_map.insert(make_pair(val, key));
    4.43        Map::set(key, val);
    4.44      }
    4.45  
    4.46 @@ -78,21 +78,89 @@
    4.47  
    4.48      virtual void erase(const Key&) {
    4.49        Value val = Map::operator[](key);
    4.50 -      InverseMap::iterator it = invMap.find(val);
    4.51 -      if (it != invMap.end() && it->second == key) {
    4.52 +      typename InverseMap::iterator it = inv_map.find(val);
    4.53 +      if (it != inv_map.end() && it->second == key) {
    4.54  	invMap.erase(it);
    4.55        }
    4.56        Map::erase(key);
    4.57      }
    4.58  
    4.59      const InverseMap& inverse() const {
    4.60 -      return invMap;
    4.61 +      return inv_map;
    4.62      } 
    4.63  
    4.64  
    4.65    private:
    4.66 -    InverseMap invMap;    
    4.67 +    InverseMap inv_map;    
    4.68    };
    4.69  
    4.70 +
    4.71 +  // unique, continous, mutable
    4.72 +
    4.73 +  template <
    4.74 +    typename _Graph,   
    4.75 +    typename _Item,
    4.76 +    typename _ItemIt,
    4.77 +    typename _Map
    4.78 +  >
    4.79 +  class DescriptorMap : protected _Map {
    4.80 +  public:
    4.81 +    typedef _Graph Graph;
    4.82 +    typedef _Item Item;
    4.83 +    typedef _ItemIt ItemIt;
    4.84 +    typedef _Map Map;
    4.85 +
    4.86 +
    4.87 +    typedef typename _Map::Key Key;
    4.88 +    typedef typename _Map::Value Value;
    4.89 +
    4.90 +    typedef vector<Item> InverseMap;
    4.91 +
    4.92 +    DescriptorMap(const Graph& _graph) : Map(_graph) {
    4.93 +      build();
    4.94 +    }
    4.95 +
    4.96 +    virtual void add(const Item& item) {
    4.97 +      Map::add(item);
    4.98 +      Map::set(item, inv_map.size());
    4.99 +      inv_map.push_back(item);
   4.100 +    }
   4.101 +
   4.102 +    virtual void erase(const Item& item) {
   4.103 +      Map::set(inv_map.back(), Map::operator[](item));
   4.104 +      inv_map[Map::operator[](item)] = inv_map.back();
   4.105 +      Map::erase(item);
   4.106 +    }
   4.107 +
   4.108 +    virtual void build() {
   4.109 +      Map::build();
   4.110 +      for (ItemIt it(*Map::getGraph()); it != INVALID; ++it) {
   4.111 +	Map::set(it, inv_map.size());
   4.112 +	inv_map.push_back(it);	
   4.113 +      }      
   4.114 +    }
   4.115 +    
   4.116 +    virtual void clear() {
   4.117 +      inv_map.clear();
   4.118 +      Map::clear();
   4.119 +    }
   4.120 +
   4.121 +    int operator[](const Item& item) const {
   4.122 +      return Map::operator[](item);
   4.123 +    }
   4.124 +
   4.125 +    
   4.126 +    const InverseMap inverse() const {
   4.127 +      return inv_map;
   4.128 +    }
   4.129 +
   4.130 +  private:
   4.131 +    vector<Item> inv_map;
   4.132 +  };
   4.133 +
   4.134 +  // unique, immutable => IDMap
   4.135 +  
   4.136 +  
   4.137 +
   4.138  }
   4.139  
     5.1 --- a/src/work/deba/test.lgf	Tue Dec 14 19:26:50 2004 +0000
     5.2 +++ b/src/work/deba/test.lgf	Wed Dec 15 19:56:55 2004 +0000
     5.3 @@ -19,9 +19,11 @@
     5.4  3 	5	5	29 	"A -> B \t: 10q"	b
     5.5  3	4	2	92 	"A -> B \t: 10a"	c
     5.6  2	3	6	92	"A -> B \t: 10d"	d
     5.7 -9	5	9 	49	"A -> B \t: 10c"	e
     5.8 +6	5	9  	49	"A -> B \t: 10c"	e
     5.9  10	4	3	40	"A -> B \t: 10v"	f
    5.10  1	3	8	84	"A -> B \t: 10g"	g
    5.11 +  #
    5.12 + # kajla
    5.13  6	7	4	83 	"A -> B \t: 10h"	h
    5.14  8	9	7	37 	"A -> B \t: 10j"	i
    5.15  7	8	10	12 	"A -> B \t: 10g"	j