[Lemon-commits] [lemon_svn] deba: r1427 - hugo/trunk/src/work/deba

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:45:22 CET 2006


Author: deba
Date: Wed Dec 15 20:56:55 2004
New Revision: 1427

Added:
   hugo/trunk/src/work/deba/graph_writer.h
Modified:
   hugo/trunk/src/work/deba/graph_io_test.cc
   hugo/trunk/src/work/deba/graph_reader.h
   hugo/trunk/src/work/deba/map_utils.h
   hugo/trunk/src/work/deba/test.lgf

Log:
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



Modified: hugo/trunk/src/work/deba/graph_io_test.cc
==============================================================================
--- hugo/trunk/src/work/deba/graph_io_test.cc	(original)
+++ hugo/trunk/src/work/deba/graph_io_test.cc	Wed Dec 15 20:56:55 2004
@@ -1,5 +1,10 @@
 #include <lemon/smart_graph.h>
+
+#include "map_utils.h"
+
+
 #include "graph_reader.h"
+#include "graph_writer.h"
 
 #include <iostream>
 #include <fstream>
@@ -11,17 +16,30 @@
   ifstream input("test.lgf");
   SmartGraph graph;
   GraphReader<SmartGraph> reader(input, graph);
+
   SmartGraph::NodeMap<int> id(graph);
   reader.readNodeMap("id", id);
+
   SmartGraph::NodeMap<int> cost(graph);
   reader.readNodeMap("cost", cost);
+ 
   SmartGraph::NodeMap<string> color(graph);
   reader.readNodeMap("color", color);
+
   SmartGraph::NodeMap<string> description(graph);
   reader.readNodeMap<QuotedStringReader>("description", description);
+
   SmartGraph::EdgeMap<char> mmap(graph);
   reader.readEdgeMap("mmap", mmap);
+
   reader.skipEdgeMap<QuotedStringReader>("description");
+
+  SmartGraph::Node source;
+  reader.readNode("source", source);
+  
+  SmartGraph::Edge newedge;
+  reader.readEdge("newedge", newedge);
+
   try {
     reader.read();
   } catch (IOException& e) {
@@ -36,5 +54,26 @@
   for (SmartGraph::EdgeIt it(graph); it != INVALID; ++it) {
     cout << mmap[it] << ' ' << id[graph.source(it)] << ' ' << id[graph.target(it)]  << endl;
   }
+
+  cout << id[source] << ' ' << cost[source] << ' ' << color[source] << ' ' << description[source] << endl;
+  cout << mmap[newedge] << ' ' << id[graph.source(newedge)] << ' ' << id[graph.target(newedge)]  << endl;
+
+  ofstream output("copy.lgf");
+  GraphWriter<SmartGraph> writer(output, graph);
+  
+  DescriptorMap<SmartGraph, SmartGraph::Node, SmartGraph::NodeIt, SmartGraph::NodeMap<int> > node_ids(graph);
+  
+  writer.writeNodeMap("id", node_ids);
+  writer.writeNodeMap<QuotedStringWriter>("format", description);
+
+  DescriptorMap<SmartGraph, SmartGraph::Edge, SmartGraph::EdgeIt, SmartGraph::EdgeMap<int> > edge_ids(graph);
+
+  writer.writeEdgeMap("id", edge_ids);
+  writer.writeEdgeMap("chars", mmap);
+  
+  writer.writeNode("source", node_ids.inverse()[3]);
+  writer.writeEdge("elek", edge_ids.inverse()[6]);
+  writer.write();
+  
   return 0;
 }

Modified: hugo/trunk/src/work/deba/graph_reader.h
==============================================================================
--- hugo/trunk/src/work/deba/graph_reader.h	(original)
+++ hugo/trunk/src/work/deba/graph_reader.h	Wed Dec 15 20:56:55 2004
@@ -24,6 +24,8 @@
 #include <map>
 #include <vector>
 
+#include <memory>
+
 #include <lemon/error.h>
 
 /// \todo fix exceptions
@@ -48,11 +50,21 @@
     }
   };
 
-  class StreamException : public IOException {
+  template <typename _Exception>
+  class StreamException : public _Exception {
   public:
-    virtual int line() = 0;
+    typedef _Exception Exception;
+    StreamException(int _line, Exception _exception) 
+      : line_num(_line), Exception(_exception) {}
+    virtual int line() const {
+      return line_num;
+    }
+    virtual std::string what() const {
+      ostringstream os;
+      os << Exception::what() << " in line " << line();
+      return os.str();
+    }
   private:
-    IOException* exception;
     int line_num;
   };  
 
@@ -84,7 +96,7 @@
       char c;
       value.clear();
       is >> ws;
-      if (!is.get(c) || c != '\"') throw DataFormatException("Quoted string format exception");
+      if (!is.get(c) || c != '\"') throw DataFormatException("Quoted string format");
       while (is.get(c) && c != '\"') {
 	if (escaped && c == '\\') {
 	  value += readEscape(is);
@@ -92,7 +104,7 @@
 	  value += c;
 	}
       }
-      if (!is) throw DataFormatException("Quoted string format exception");
+      if (!is) throw DataFormatException("Quoted string format");
     }
 
   private:
@@ -171,7 +183,6 @@
   
   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   class GraphReader {
-
   public:
     
     typedef _Graph Graph;
@@ -181,22 +192,24 @@
     typedef _ReaderTraits ReaderTraits;
     typedef typename ReaderTraits::DefaultReader DefaultReader;
 
-    GraphReader(istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader()) 
+    GraphReader(std::istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader()) 
       : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {}
 
 
     ~GraphReader() {
 
-      for (typename NodeReaders::iterator it = node_readers.begin(); it != node_readers.end(); ++it) {
+      for (typename NodeMapReaders::iterator it = node_map_readers.begin(); it != node_map_readers.end(); ++it) {
 	delete it->second;
       }
 
-      for (typename EdgeReaders::iterator it = edge_readers.begin(); it != edge_readers.end(); ++it) {
+      for (typename EdgeMapReaders::iterator it = edge_map_readers.begin(); it != edge_map_readers.end(); ++it) {
 	delete it->second;
       }
 
     }
 
+    // Node map rules
+
     template <typename Map>
     GraphReader& readNodeMap(std::string name, Map& map) {
       return readNodeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map);
@@ -204,26 +217,24 @@
 
     template <typename Reader, typename Map>
     GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) {
-      if (node_readers.find(name) != node_readers.end()) {
-	Exception e;
-	e << "Multiple read rule for node map: " << name;
-	throw e;
+      if (node_map_readers.find(name) != node_map_readers.end()) {
+	throw Exception() << "Multiple read rule for node map: " << name;
       }
-      node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
+      node_map_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
       return *this;
     }
 
     template <typename Reader>
     GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) {
-      if (node_readers.find(name) != node_readers.end()) {
-	Exception e;
-	e << "Multiple read rule for node map: " << name;
-	throw e;
+      if (node_map_readers.find(name) != node_map_readers.end()) {
+	throw Exception() << "Multiple read rule for node map: " << name;
       }
-      node_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
+      node_map_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
       return *this;
     }
 
+    // Edge map rules
+
     template <typename Map>
     GraphReader& readEdgeMap(std::string name, Map& map) { 
       return readEdgeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map);
@@ -232,81 +243,106 @@
 
     template <typename Reader, typename Map>
     GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) {
-      if (edge_readers.find(name) != edge_readers.end()) {
-	Exception e;
-	e << "Multiple read rule for edge map: " << name;
-	throw e;
+      if (edge_map_readers.find(name) != edge_map_readers.end()) {
+	throw Exception() << "Multiple read rule for edge map: " << name;
       }
-      edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
+      edge_map_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
       return *this;
     }
 
     template <typename Reader>
     GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) {
-      if (edge_readers.find(name) != edge_readers.end()) {
-	Exception e;
-	e << "Multiple read rule for edge map: " << name;
-	throw e;
+      if (edge_map_readers.find(name) != edge_map_readers.end()) {
+	throw Exception() << "Multiple read rule for edge map: " << name;
       }
-      edge_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
+      edge_map_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
       return *this;
     }
 
+    // Node rules
+    GraphReader& readNode(std::string name, Node& node) {
+      if (node_readers.find(name) != node_readers.end()) {
+	throw Exception() << "Multiple read rule for node";
+      }
+      node_readers.insert(make_pair(name, &node));
+    }
+
+    // Edge rules
+
+    GraphReader& readEdge(std::string name, Edge& edge) {
+      if (edge_readers.find(name) != edge_readers.end()) {
+	throw Exception() << "Multiple read rule for edge";
+      }
+      edge_readers.insert(make_pair(name, &edge));
+    }
+
     void read() {
       int line_num = 0;
-      InverterBase<Node>* nodeInverter = 0;
-      InverterBase<Edge>* edgeInverter = 0;
-      // \todo delete the inverters
-      //      try {
-	{
-	  std::string line = readNotEmptyLine(is, line_num);
+      std::auto_ptr<InverterBase<Node> > nodeInverter;
+      std::auto_ptr<InverterBase<Edge> > edgeInverter;
+      try {
+	std::string line = readNotEmptyLine(is, line_num);
+	if (line.find("@nodeset") == 0) {
+	  line = readNodeSet(line_num, nodeInverter);
+	} 
+	if (line.find("@edgeset") == 0) {
+	  line = readEdgeSet(line_num, edgeInverter, nodeInverter);
+	}
+	if (line.find("@nodes") == 0) {
+	  line = readNodes(line_num, nodeInverter);
+	}
+	if (line.find("@edges") == 0) {
+	  line = readEdges(line_num, edgeInverter);
+	}
+	if (line.find("@end") != 0) {
+	  throw DataFormatException("Invalid control sequence: " + line);
 	}
-	readNodeSet(line_num, nodeInverter);
-	readEdgeSet(line_num, edgeInverter, nodeInverter);
-	//      } catch (...){
-	if (nodeInverter != 0) delete nodeInverter;
-	if (edgeInverter != 0) delete edgeInverter;
-	//      }
+      } catch (DataFormatException e) {
+	throw StreamException<DataFormatException>(line_num, e);
+      }
     }
 
   private:
 
     template <typename Item> class InverterBase;
-    //    template <typename Item> class InverterBase;
 
-    void readNodeSet(int& line_num, InverterBase<Node>* & nodeInverter) {
-      int n = 0;
-      std::vector<ReaderBase<Node>*> index;
+    std::string readNodeSet(int& line_num, auto_ptr<InverterBase<Node> > & nodeInverter) {
+      std::vector<ReaderBase<Node>* > index;
       {
 	std::string line = readNotEmptyLine(is, line_num);    
 	std::string id;
 	std::istringstream ls(line);	
 	while (ls >> id) {
 	  if (id[0] == '#') break;
-	  typename NodeReaders::iterator it = node_readers.find(id);
-	  if (it != node_readers.end()) {
+	  typename NodeMapReaders::iterator it = node_map_readers.find(id);
+	  if (it != node_map_readers.end()) {
 	    index.push_back(it->second);
+	    node_map_readers.erase(it);
 	  } else {
 	    index.push_back(&nodeSkipper);
 	  }
-	  ++n;
 	}
       }
 
-      nodeInverter = index[0]->getInverter();
+      if (index.size() == 0) {
+	throw DataFormatException("No node map found");
+      }
+
+      nodeInverter = auto_ptr<InverterBase<Node> >(index[0]->getInverter());
       std::string line;
       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
 	Node node = graph.addNode();
 	std::istringstream ls(line);
 	nodeInverter->read(ls, node);
-	for (int i = 1; i < n; ++i) {
+	for (int i = 1; i < index.size(); ++i) {
 	  index[i]->read(ls, node);
 	}
       }
+      return line;
     }
 
-    void readEdgeSet(int& line_num, InverterBase<Edge>* & edgeInverter, InverterBase<Node>* & nodeInverter) {
-      int n = 0;
+    std::string readEdgeSet(int& line_num, 
+		     auto_ptr<InverterBase<Edge> > & edgeInverter, auto_ptr<InverterBase<Node> > & nodeInverter) {
       std::vector<ReaderBase<Edge>*> index;
       {
 	std::string line = readNotEmptyLine(is, line_num);    
@@ -314,16 +350,21 @@
 	std::istringstream ls(line);	
 	while (ls >> id) {
 	  if (id[0] == '#') break;
-	  typename EdgeReaders::iterator it = edge_readers.find(id);
-	  if (it != edge_readers.end()) {
+	  typename EdgeMapReaders::iterator it = edge_map_readers.find(id);
+	  if (it != edge_map_readers.end()) {
 	    index.push_back(it->second);
+	    edge_map_readers.erase(it);
 	  } else {
 	    index.push_back(&edgeSkipper);
 	  }
-	  ++n;
 	}
       }
-      edgeInverter = index[0]->getInverter();
+
+      if (index.size() == 0) {
+	throw DataFormatException("No edge map found");
+      }
+
+      edgeInverter = auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
       std::string line;
       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	
 	std::istringstream ls(line);
@@ -331,10 +372,39 @@
 	Node target = nodeInverter->read(ls);
 	Edge edge = graph.addEdge(source, target);
 	edgeInverter->read(ls, edge);
-	for (int i = 1; i < n; ++i) {
+	for (int i = 1; i < index.size(); ++i) {
 	  index[i]->read(ls, edge);
 	}
       }      
+      return line;
+    }
+
+    std::string readNodes(int& line_num, auto_ptr<InverterBase<Node> >& nodeInverter) {
+      std::string line;
+      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
+	std::istringstream ls(line);
+	std::string name;
+	ls >> name;
+	typename NodeReaders::iterator it = node_readers.find(name);
+	if (it != node_readers.end()) {
+	  *(it -> second) = nodeInverter->read(ls);
+	} 
+      }        
+      return line;
+    }
+
+    std::string readEdges(int& line_num, auto_ptr<InverterBase<Edge> >& edgeInverter) {
+      std::string line;
+      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
+	std::istringstream ls(line);
+	std::string name;
+	ls >> name;
+	typename EdgeReaders::iterator it = edge_readers.find(name);
+	if (it != edge_readers.end()) {
+	  *(it -> second) = edgeInverter->read(ls);
+	} 
+      }        
+      return line;    
     }
 
     std::string readNotEmptyLine(std::istream& is, int& line_num) {
@@ -345,15 +415,18 @@
 	  return line.substr(vi);
 	}
       }
-      throw Exception();
+      throw DataFormatException("End of stream");
     }
     
+    // Inverters store and give back the Item from the id,
+    // and may put the ids into a map.
+    
     template <typename _Item>
     class InverterBase {
     public:
       typedef _Item Item;
-      virtual void read(istream&, const Item&) = 0;
-      virtual Item read(istream&) = 0;
+      virtual void read(std::istream&, const Item&) = 0;
+      virtual Item read(std::istream&) = 0;
     };
 
     template <typename _Item, typename _Map, typename _Reader>
@@ -372,7 +445,7 @@
       MapReaderInverter(Map& _map, const Reader& _reader) 
 	: map(_map), reader(_reader) {}
 
-      virtual void read(istream& is, const Item& item) {
+      virtual void read(std::istream& is, const Item& item) {
 	Value value;
 	reader.read(is, value);
 	map.set(item, value);
@@ -384,7 +457,7 @@
 	}
       }
 
-      virtual Item read(istream& is) {
+      virtual Item read(std::istream& is) {
 	Value value;
 	reader.read(is, value);	
 	typename Inverse::const_iterator it = inverse.find(value);
@@ -409,7 +482,7 @@
       SkipReaderInverter(const Reader& _reader) 
 	: reader(_reader) {}
 
-      virtual void read(istream& is, const Item& item) {
+      virtual void read(std::istream& is, const Item& item) {
 	Value value;
 	reader.read(is, value);
 	typename Inverse::iterator it = inverse.find(value);
@@ -420,7 +493,7 @@
 	}
       }
 
-      virtual Item read(istream& is) {
+      virtual Item read(std::istream& is) {
 	Value value;
 	reader.read(is, value);	
 	typename Inverse::const_iterator it = inverse.find(value);
@@ -434,12 +507,14 @@
       Inverse inverse;
     };
 
+    // Readers
 
     template <typename _Item>    
     class ReaderBase {
     public:
       typedef _Item Item;
-      virtual void read(istream& is, const Item& item) = 0;
+
+      virtual void read(std::istream& is, const Item& item) = 0;
       virtual InverterBase<_Item>* getInverter() = 0;
     };
 
@@ -458,7 +533,7 @@
 	: map(_map), reader(_reader) {}
 
 
-      virtual void read(istream& is, const Item& item) {
+      virtual void read(std::istream& is, const Item& item) {
 	Value value;
 	reader.read(is, value);
 	map.set(item, value);
@@ -480,7 +555,7 @@
       Reader reader;
       SkipReader(const Reader& _reader) : reader(_reader) {}
 
-      virtual void read(istream& is, const Item& item) {
+      virtual void read(std::istream& is, const Item& item) {
 	Value value;
 	reader.read(is, value);
       }      
@@ -491,10 +566,16 @@
     };
 
 
-    typedef std::map<std::string, ReaderBase<Node>* > NodeReaders;
+    typedef std::map<std::string, ReaderBase<Node>*> NodeMapReaders;
+    NodeMapReaders node_map_readers;
+
+    typedef std::map<std::string, ReaderBase<Edge>*> EdgeMapReaders;
+    EdgeMapReaders edge_map_readers;
+
+    typedef std::map<std::string, Node*> NodeReaders;
     NodeReaders node_readers;
 
-    typedef std::map<std::string, ReaderBase<Edge>* > EdgeReaders;
+    typedef std::map<std::string, Edge*> EdgeReaders;
     EdgeReaders edge_readers;
 
     std::istream& is;

Added: hugo/trunk/src/work/deba/graph_writer.h
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/deba/graph_writer.h	Wed Dec 15 20:56:55 2004
@@ -0,0 +1,324 @@
+/* -*- C++ -*-
+ * src/lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Combinatorial Optimization Research Group, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup gio
+///\file
+///\brief Graph writer.
+
+
+#include <iostream>
+#include <sstream>
+
+#include <map>
+#include <vector>
+
+#include <memory>
+
+#include <lemon/invalid.h>
+#include <lemon/error.h>
+
+
+namespace lemon {
+
+  struct DefaultWriterTraits {
+
+    template <typename _Value>
+    struct Writer {
+      typedef _Value Value;
+
+      void write(std::ostream& os, const Value& value) {
+	os << value << '\t';
+      }
+    };
+
+  };
+
+
+  class QuotedStringWriter {
+  public:
+    typedef std::string Value;
+
+    QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
+
+    void write(std::ostream& os, const std::string& value) {
+      char c;
+      os << "\"";
+      if (escaped) {
+	ostringstream ls;
+	for (int i = 0; i < value.size(); ++i) {
+	  writeEscape(ls, value[i]);
+	}
+	os << ls.str();
+      } else {
+	os << value;
+      }
+      os << "\"";
+    }
+
+  private:
+    
+    static void writeEscape(std::ostream& os, char c) {
+      switch (c) {
+      case '\\':
+	os << "\\\\";
+	return;
+      case '\"':
+	os << "\\\"";
+	return;
+      case '\'':
+	os << "\\\'";
+	return;
+      case '\?':
+	os << "\\\?";
+	return;
+      case '\a':
+	os << "\\a";
+	return;
+      case '\b':
+	os << "\\b";
+	return;
+      case '\f':
+	os << "\\f";
+	return;
+      case '\r':
+	os << "\\r";
+	return;
+      case '\n':
+	os << "\\n";
+	return;
+      case '\t':
+	os << "\\t";
+	return;
+      case '\v':
+	os << "\\v";
+	return;
+      default:
+	if (c < 0x20) {
+	  os << '\\' << oct << (int)c;
+	} else {
+	  os << c;
+	}
+	return;
+      }     
+    }
+  private:
+    bool escaped;
+  };
+
+  // Graph writer
+  
+  template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
+  class GraphWriter {
+  public:
+    
+    typedef _Graph Graph;
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::Edge Edge;
+    typedef typename Graph::EdgeIt EdgeIt;
+
+    typedef _WriterTraits WriterTraits;
+
+    GraphWriter(std::ostream& _os, Graph& _graph) : os(_os), graph(_graph) {}
+
+
+    ~GraphWriter() {
+
+      for (typename NodeMapWriters::iterator it = node_map_writers.begin(); it != node_map_writers.end(); ++it) {
+	delete it->second;
+      }
+
+      for (typename EdgeMapWriters::iterator it = edge_map_writers.begin(); it != edge_map_writers.end(); ++it) {
+	delete it->second;
+      }
+
+    }
+
+    // Node map rules
+
+    template <typename Map>
+    GraphWriter& writeNodeMap(std::string name, const Map& map) {
+      return writeNodeMap<typename WriterTraits::template Writer<typename Map::Value>, Map>(name, map);
+    }
+
+    template <typename Writer, typename Map>
+    GraphWriter& writeNodeMap(std::string name, const Map& map, const Writer& writer = Writer()) {
+      //      if (node_map_writers.find(name) != node_map_writers.end()) {
+      //	throw Exception() << "Multiple write rule for node map: " << name;
+      //      }
+      node_map_writers.push_back(make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
+      return *this;
+    }
+
+    // Edge map rules
+
+    template <typename Map>
+    GraphWriter& writeEdgeMap(std::string name, const Map& map) { 
+      return writeEdgeMap<typename WriterTraits::template Writer<typename Map::Value>, Map>(name, map);
+    }
+
+
+    template <typename Writer, typename Map>
+    GraphWriter& writeEdgeMap(std::string name, const Map& map, const Writer& writer = Writer()) {
+      //      if (edge_map_writers.find(name) != edge_map_writers.end()) {
+      //	throw Exception() << "Multiple write rule for edge map: " << name;
+      //      }
+      edge_map_writers.push_back(make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
+      return *this;
+    }
+
+    // Node rules
+    GraphWriter& writeNode(std::string name, const Node& node) {
+      //      if (node_writers.find(name) != node_writers.end()) {
+      //	throw Exception() << "Multiple write rule for node";
+      //      }
+      node_writers.push_back(make_pair(name, node));
+    }
+
+    // Edge rules
+
+    GraphWriter& writeEdge(std::string name, const Edge& edge) {
+      //      if (edge_writers.find(name) != edge_writers.end()) {
+      //	throw Exception() << "Multiple write rule for edge";
+      //      }
+      edge_writers.push_back(make_pair(name, edge));
+    }
+
+    void write() {   
+      writeNodeSet();
+      writeEdgeSet();
+      writeNodes();
+      writeEdges();
+      os << "@end" << std::endl;
+    }
+
+  private:
+
+    void writeNodeSet() {
+      if (node_map_writers.size() == 0) return;
+      os << "@nodeset" << std::endl;
+      for (int i = 0; i < node_map_writers.size(); ++i) {
+	os << node_map_writers[i].first << '\t';
+      } 
+      os << std::endl;
+      for (NodeIt it(graph); it != INVALID; ++it) {
+	for (int i = 0; i < node_map_writers.size(); ++i) {
+	  node_map_writers[i].second->write(os, it);
+	}
+	os << std::endl;
+      }
+
+    }
+
+    void writeEdgeSet() {
+      if (edge_map_writers.size() == 0) return;
+      if (node_map_writers.size() == 0) {
+	throw Exception() << "Missing node id map";
+      }
+      os << "@edgeset" << std::endl;
+      os << "\t\t";
+      for (int i = 0; i < edge_map_writers.size(); ++i) {
+	os << edge_map_writers[i].first << '\t';
+      } 
+      os << std::endl;
+      for (EdgeIt it(graph); it != INVALID; ++it) {
+	node_map_writers[0].second->write(os, graph.source(it));
+	node_map_writers[0].second->write(os, graph.target(it));
+	for (int i = 0; i < edge_map_writers.size(); ++i) {
+	  edge_map_writers[i].second->write(os, it);
+	}
+	os << std::endl;
+      }
+    }
+
+    void writeNodes() {
+      if (node_writers.size() == 0) return;
+      if (node_map_writers.size() == 0) {
+	throw Exception() << "Missing node id map";
+      }
+      os << "@nodes" << std::endl;
+      for (int i = 0; i < node_writers.size(); ++i) {
+	os << node_writers[i].first << '\t';
+	node_map_writers[0].second->write(os, node_writers[i].second);
+	os << std::endl;
+      } 
+    }
+
+    void writeEdges() {
+      if (edge_writers.size() == 0) return;
+      if (edge_map_writers.size() == 0) {
+	throw Exception() << "Missing edge id map";
+      }
+      os << "@edges" << std::endl;
+      for (int i = 0; i < edge_writers.size(); ++i) {
+	os << edge_writers[i].first << '\t';
+	edge_map_writers[0].second->write(os, edge_writers[i].second);
+	os << std::endl;
+      } 
+    }
+    
+    // Writers
+
+    template <class _Item>
+    class WriterBase {
+    public:
+      typedef _Item Item;
+      virtual void write(std::ostream&, const Item&) = 0;
+    };
+
+    template <class _Item, typename _Map, typename _Writer>
+    class MapWriter : public WriterBase<_Item> {
+    public:
+      typedef _Map Map;
+      typedef _Writer Writer;
+      typedef typename Writer::Value Value;
+      typedef _Item Item;
+      
+      const Map& map;
+      Writer writer;
+
+      MapWriter(const Map& _map, const Writer& _writer) 
+	: map(_map), writer(_writer) {}
+
+
+      virtual void write(std::ostream& os, const Item& item) {
+	Value value;
+	writer.write(os, map[item]);
+      }
+
+    };
+
+
+
+    typedef std::vector< std::pair<std::string, WriterBase<Node>*> > NodeMapWriters;
+    NodeMapWriters node_map_writers;
+
+    typedef std::vector< std::pair<std::string, WriterBase<Edge>*> > EdgeMapWriters;
+    EdgeMapWriters edge_map_writers;
+
+    typedef std::vector<std::pair<std::string, Node> > NodeWriters;
+    NodeWriters node_writers;
+
+    typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
+    EdgeWriters edge_writers;
+
+    std::ostream& os;
+    Graph& graph;
+
+  };
+
+
+}

Modified: hugo/trunk/src/work/deba/map_utils.h
==============================================================================
--- hugo/trunk/src/work/deba/map_utils.h	(original)
+++ hugo/trunk/src/work/deba/map_utils.h	Wed Dec 15 20:56:55 2004
@@ -35,19 +35,19 @@
   /// in the inverse map.
   template <
     typename _Graph, 
-    typename _Map, 
-    template <typename, typename> class _InvMap = std::Map
+    typename _Map
   >
   class InversableMap : protected _Map {
 
   public:
+    typedef _Graph Graph;
 
-    typename _Map Map;
-    typename _InvMap<Map::Value, Map::Key> InverseMap;
+    typedef _Map Map;
+    typedef typename _Map::Key Key;
+    typedef typename _Map::Value Value;
+    typedef std::map<Value, Key> InverseMap;
     
-    typename _Map::Key Key;
-    typename _Map::Value Value;
-    typename _Map::ConstReference ConstReference;
+    typedef typename _Map::ConstReference ConstReference;
 
     /// Constructor.
 
@@ -60,11 +60,11 @@
     /// It sets the map and the inverse map 
     void set(const Key& key, const Value& val) {
       Value oldval = Map::operator[](key);
-      InverseMap::iterator it = invMap.find(oldval);
-      if (it != invMap.end() && it->second == key) {
-	invMap.erase(it);
+      typename InverseMap::iterator it = inv_map.find(oldval);
+      if (it != inv_map.end() && it->second == key) {
+	inv_map.erase(it);
       }      
-      invMap.insert(make_pair(val, key));
+      inv_map.insert(make_pair(val, key));
       Map::set(key, val);
     }
 
@@ -78,21 +78,89 @@
 
     virtual void erase(const Key&) {
       Value val = Map::operator[](key);
-      InverseMap::iterator it = invMap.find(val);
-      if (it != invMap.end() && it->second == key) {
+      typename InverseMap::iterator it = inv_map.find(val);
+      if (it != inv_map.end() && it->second == key) {
 	invMap.erase(it);
       }
       Map::erase(key);
     }
 
     const InverseMap& inverse() const {
-      return invMap;
+      return inv_map;
     } 
 
 
   private:
-    InverseMap invMap;    
+    InverseMap inv_map;    
+  };
+
+
+  // unique, continous, mutable
+
+  template <
+    typename _Graph,   
+    typename _Item,
+    typename _ItemIt,
+    typename _Map
+  >
+  class DescriptorMap : protected _Map {
+  public:
+    typedef _Graph Graph;
+    typedef _Item Item;
+    typedef _ItemIt ItemIt;
+    typedef _Map Map;
+
+
+    typedef typename _Map::Key Key;
+    typedef typename _Map::Value Value;
+
+    typedef vector<Item> InverseMap;
+
+    DescriptorMap(const Graph& _graph) : Map(_graph) {
+      build();
+    }
+
+    virtual void add(const Item& item) {
+      Map::add(item);
+      Map::set(item, inv_map.size());
+      inv_map.push_back(item);
+    }
+
+    virtual void erase(const Item& item) {
+      Map::set(inv_map.back(), Map::operator[](item));
+      inv_map[Map::operator[](item)] = inv_map.back();
+      Map::erase(item);
+    }
+
+    virtual void build() {
+      Map::build();
+      for (ItemIt it(*Map::getGraph()); it != INVALID; ++it) {
+	Map::set(it, inv_map.size());
+	inv_map.push_back(it);	
+      }      
+    }
+    
+    virtual void clear() {
+      inv_map.clear();
+      Map::clear();
+    }
+
+    int operator[](const Item& item) const {
+      return Map::operator[](item);
+    }
+
+    
+    const InverseMap inverse() const {
+      return inv_map;
+    }
+
+  private:
+    vector<Item> inv_map;
   };
 
+  // unique, immutable => IDMap
+  
+  
+
 }
 

Modified: hugo/trunk/src/work/deba/test.lgf
==============================================================================
--- hugo/trunk/src/work/deba/test.lgf	(original)
+++ hugo/trunk/src/work/deba/test.lgf	Wed Dec 15 20:56:55 2004
@@ -19,9 +19,11 @@
 3 	5	5	29 	"A -> B \t: 10q"	b
 3	4	2	92 	"A -> B \t: 10a"	c
 2	3	6	92	"A -> B \t: 10d"	d
-9	5	9 	49	"A -> B \t: 10c"	e
+6	5	9  	49	"A -> B \t: 10c"	e
 10	4	3	40	"A -> B \t: 10v"	f
 1	3	8	84	"A -> B \t: 10g"	g
+  #
+ # kajla
 6	7	4	83 	"A -> B \t: 10h"	h
 8	9	7	37 	"A -> B \t: 10j"	i
 7	8	10	12 	"A -> B \t: 10g"	j



More information about the Lemon-commits mailing list