# HG changeset patch # User deba # Date 1103140615 0 # Node ID 3eaff8d041714b3a31fd43ed8be9aeed42e750ba # Parent 2f514b5c7122253e865c16b6a6ba8929e2a1a9b1 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 diff -r 2f514b5c7122 -r 3eaff8d04171 src/work/deba/graph_io_test.cc --- a/src/work/deba/graph_io_test.cc Tue Dec 14 19:26:50 2004 +0000 +++ b/src/work/deba/graph_io_test.cc Wed Dec 15 19:56:55 2004 +0000 @@ -1,5 +1,10 @@ #include + +#include "map_utils.h" + + #include "graph_reader.h" +#include "graph_writer.h" #include #include @@ -11,17 +16,30 @@ ifstream input("test.lgf"); SmartGraph graph; GraphReader reader(input, graph); + SmartGraph::NodeMap id(graph); reader.readNodeMap("id", id); + SmartGraph::NodeMap cost(graph); reader.readNodeMap("cost", cost); + SmartGraph::NodeMap color(graph); reader.readNodeMap("color", color); + SmartGraph::NodeMap description(graph); reader.readNodeMap("description", description); + SmartGraph::EdgeMap mmap(graph); reader.readEdgeMap("mmap", mmap); + reader.skipEdgeMap("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 writer(output, graph); + + DescriptorMap > node_ids(graph); + + writer.writeNodeMap("id", node_ids); + writer.writeNodeMap("format", description); + + DescriptorMap > 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; } diff -r 2f514b5c7122 -r 3eaff8d04171 src/work/deba/graph_reader.h --- a/src/work/deba/graph_reader.h Tue Dec 14 19:26:50 2004 +0000 +++ b/src/work/deba/graph_reader.h Wed Dec 15 19:56:55 2004 +0000 @@ -24,6 +24,8 @@ #include #include +#include + #include /// \todo fix exceptions @@ -48,11 +50,21 @@ } }; - class StreamException : public IOException { + template + 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 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 GraphReader& readNodeMap(std::string name, Map& map) { return readNodeMap, Map>(name, map); @@ -204,26 +217,24 @@ template 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(map, reader))); + node_map_readers.insert(make_pair(name, new MapReader(map, reader))); return *this; } template 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(reader))); + node_map_readers.insert(make_pair(name, new SkipReader(reader))); return *this; } + // Edge map rules + template GraphReader& readEdgeMap(std::string name, Map& map) { return readEdgeMap, Map>(name, map); @@ -232,81 +243,106 @@ template 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(map, reader))); + edge_map_readers.insert(make_pair(name, new MapReader(map, reader))); return *this; } template GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) { + if (edge_map_readers.find(name) != edge_map_readers.end()) { + throw Exception() << "Multiple read rule for edge map: " << name; + } + edge_map_readers.insert(make_pair(name, new SkipReader(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()) { - Exception e; - e << "Multiple read rule for edge map: " << name; - throw e; + throw Exception() << "Multiple read rule for edge"; } - edge_readers.insert(make_pair(name, new SkipReader(reader))); - return *this; + edge_readers.insert(make_pair(name, &edge)); } void read() { int line_num = 0; - InverterBase* nodeInverter = 0; - InverterBase* edgeInverter = 0; - // \todo delete the inverters - // try { - { - std::string line = readNotEmptyLine(is, line_num); + std::auto_ptr > nodeInverter; + std::auto_ptr > 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); } - readNodeSet(line_num, nodeInverter); - readEdgeSet(line_num, edgeInverter, nodeInverter); - // } catch (...){ - if (nodeInverter != 0) delete nodeInverter; - if (edgeInverter != 0) delete edgeInverter; - // } + 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); + } + } catch (DataFormatException e) { + throw StreamException(line_num, e); + } } private: template class InverterBase; - // template class InverterBase; - void readNodeSet(int& line_num, InverterBase* & nodeInverter) { - int n = 0; - std::vector*> index; + std::string readNodeSet(int& line_num, auto_ptr > & nodeInverter) { + std::vector* > 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 >(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* & edgeInverter, InverterBase* & nodeInverter) { - int n = 0; + std::string readEdgeSet(int& line_num, + auto_ptr > & edgeInverter, auto_ptr > & nodeInverter) { std::vector*> 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 >(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 >& 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 >& 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 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 @@ -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 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* > NodeReaders; + typedef std::map*> NodeMapReaders; + NodeMapReaders node_map_readers; + + typedef std::map*> EdgeMapReaders; + EdgeMapReaders edge_map_readers; + + typedef std::map NodeReaders; NodeReaders node_readers; - typedef std::map* > EdgeReaders; + typedef std::map EdgeReaders; EdgeReaders edge_readers; std::istream& is; diff -r 2f514b5c7122 -r 3eaff8d04171 src/work/deba/graph_writer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/deba/graph_writer.h Wed Dec 15 19:56:55 2004 +0000 @@ -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 +#include + +#include +#include + +#include + +#include +#include + + +namespace lemon { + + struct DefaultWriterTraits { + + template + 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 + 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 + GraphWriter& writeNodeMap(std::string name, const Map& map) { + return writeNodeMap, Map>(name, map); + } + + template + 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(map, writer))); + return *this; + } + + // Edge map rules + + template + GraphWriter& writeEdgeMap(std::string name, const Map& map) { + return writeEdgeMap, Map>(name, map); + } + + + template + 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(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 WriterBase { + public: + typedef _Item Item; + virtual void write(std::ostream&, const Item&) = 0; + }; + + template + 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*> > NodeMapWriters; + NodeMapWriters node_map_writers; + + typedef std::vector< std::pair*> > EdgeMapWriters; + EdgeMapWriters edge_map_writers; + + typedef std::vector > NodeWriters; + NodeWriters node_writers; + + typedef std::vector > EdgeWriters; + EdgeWriters edge_writers; + + std::ostream& os; + Graph& graph; + + }; + + +} diff -r 2f514b5c7122 -r 3eaff8d04171 src/work/deba/map_utils.h --- a/src/work/deba/map_utils.h Tue Dec 14 19:26:50 2004 +0000 +++ b/src/work/deba/map_utils.h Wed Dec 15 19:56:55 2004 +0000 @@ -35,19 +35,19 @@ /// in the inverse map. template < typename _Graph, - typename _Map, - template class _InvMap = std::Map + typename _Map > class InversableMap : protected _Map { public: + typedef _Graph Graph; - typename _Map Map; - typename _InvMap InverseMap; + typedef _Map Map; + typedef typename _Map::Key Key; + typedef typename _Map::Value Value; + typedef std::map 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 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 inv_map; + }; + + // unique, immutable => IDMap + + + } diff -r 2f514b5c7122 -r 3eaff8d04171 src/work/deba/test.lgf --- a/src/work/deba/test.lgf Tue Dec 14 19:26:50 2004 +0000 +++ b/src/work/deba/test.lgf Wed Dec 15 19:56:55 2004 +0000 @@ -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