deba@1032: /* -*- C++ -*- deba@1032: * src/lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library deba@1032: * deba@1032: * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@1032: * (Egervary Combinatorial Optimization Research Group, EGRES). deba@1032: * deba@1032: * Permission to use, modify and distribute this software is granted deba@1032: * provided that this copyright notice appears in all copies. For deba@1032: * precise terms see the accompanying LICENSE file. deba@1032: * deba@1032: * This software is provided "AS IS" with no warranty of any kind, deba@1032: * express or implied, and with no claim as to its suitability for any deba@1032: * purpose. deba@1032: * deba@1032: */ deba@1032: deba@1032: ///\ingroup gio deba@1032: ///\file deba@1032: ///\brief Map utilities. deba@1032: deba@1032: #include deba@1032: #include deba@1032: deba@1032: #include deba@1032: #include deba@1032: deba@1032: #include deba@1032: deba@1032: /// \todo fix exceptions deba@1032: deba@1032: deba@1032: namespace lemon { deba@1032: deba@1032: struct DefaultReaderTraits { deba@1032: deba@1032: template deba@1032: struct Reader { deba@1032: typedef _Value Value; deba@1032: void read(std::istream& is, Value& value) { deba@1032: is >> value; deba@1032: } deba@1032: }; deba@1032: deba@1032: template deba@1032: struct Skipper { deba@1032: typedef _Value Value; deba@1032: void read(std::istream& is) { deba@1032: Value tmp; deba@1032: is >> tmp; deba@1032: } deba@1032: }; deba@1032: deba@1032: struct DefaultSkipper { deba@1032: void read(std::istream& is) { deba@1032: std::string tmp; deba@1032: is >> tmp; deba@1032: } deba@1032: }; deba@1032: }; deba@1032: deba@1032: class IOException { deba@1032: virtual string message() = 0; deba@1032: }; deba@1032: deba@1032: class FileReaderException { deba@1032: virtual int getLine() = 0; deba@1032: }; deba@1032: deba@1032: deba@1032: deba@1032: template deba@1032: class GraphReader { deba@1032: deba@1032: public: deba@1032: deba@1032: typedef _Graph Graph; deba@1032: typedef typename Graph::Node Node; deba@1032: typedef typename Graph::Edge Edge; deba@1032: deba@1032: typedef _ReaderTraits ReaderTraits; deba@1032: deba@1032: deba@1032: GraphReader(std::istream& _is, Graph& _graph) : is(_is), graph(_graph) {} deba@1032: deba@1032: template deba@1032: GraphReader& readNodeMap(std::string name, Map& map, deba@1032: const typename ReaderTraits::template Reader& reader = deba@1032: typename ReaderTraits::template Reader()) { deba@1032: return readNodeMap >(name, map, reader); deba@1032: } deba@1032: deba@1032: template deba@1032: GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) { deba@1032: node_readers.insert(make_pair(name, new MapReader(map, reader))); deba@1032: return *this; deba@1032: } deba@1032: deba@1032: template deba@1032: GraphReader& readEdgeMap(std::string name, Map& map, deba@1032: const typename ReaderTraits::template Reader& reader = deba@1032: typename ReaderTraits::template Reader()) { deba@1032: return readEdgeMap >(name, map, reader); deba@1032: } deba@1032: deba@1032: template deba@1032: GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) { deba@1032: edge_readers.insert(make_pair(name, new MapReader(map, reader))); deba@1032: return *this; deba@1032: } deba@1032: deba@1032: void read() { deba@1032: int line_num = 0; deba@1032: readNodeSet(line_num); deba@1032: readEdgeSet(line_num); deba@1032: { deba@1032: std::string line = readNotEmptyLine(is, line_num); deba@1032: } deba@1032: } deba@1032: deba@1032: private: deba@1032: deba@1032: void readNodeSet(int& line_num) { deba@1032: int n = 0; deba@1032: { deba@1032: std::string line = readNotEmptyLine(is, line_num); deba@1032: } deba@1032: std::vector*> index; deba@1032: { deba@1032: std::string line = readNotEmptyLine(is, line_num); deba@1032: std::string id; deba@1032: std::istringstream ls(line); deba@1032: while (ls >> id) { deba@1032: typename map* >::iterator it = node_readers.find(id); deba@1032: if (it != node_readers.end()) { deba@1032: index.push_back(it->second); deba@1032: } else { deba@1032: index.push_back(0); deba@1032: } deba@1032: ++n; deba@1032: } deba@1032: } deba@1032: std::string line; deba@1032: while (line = readNotEmptyLine(is, line_num), line[0] != '@') { deba@1032: Node node = graph.addNode(); deba@1032: std::istringstream ls(line); deba@1032: for (int i = 0; i < n; ++i) { deba@1032: if (index[i] != 0) { deba@1032: index[i]->read(ls, node); deba@1032: } else { deba@1032: default_skipper.read(ls); deba@1032: } deba@1032: } deba@1032: } deba@1032: } deba@1032: deba@1032: void readEdgeSet(int& line_num) { deba@1032: deba@1032: } deba@1032: deba@1032: std::string readNotEmptyLine(std::istream& is, int& line_num) { deba@1032: std::string line; deba@1032: while (++line_num, getline(is, line)) { deba@1032: int vi = line.find_first_not_of(" \t"); deba@1032: if (vi != string::npos && line[vi] != '#') { deba@1032: return line.substr(vi); deba@1032: } deba@1032: } deba@1032: throw Exception(); deba@1032: } deba@1032: deba@1032: istream& is; deba@1032: Graph& graph; deba@1032: deba@1032: typename ReaderTraits::DefaultSkipper default_skipper; deba@1032: deba@1032: template deba@1032: class MapReaderBase { deba@1032: public: deba@1032: typedef _Item Item; deba@1032: virtual void read(istream& is, const Item& item) = 0; deba@1032: }; deba@1032: deba@1032: template deba@1032: class MapReader : public MapReaderBase<_Item> { deba@1032: public: deba@1032: typedef _Map Map; deba@1032: typedef _Reader Reader; deba@1032: typedef _Item Item; deba@1032: deba@1032: Map& map; deba@1032: Reader reader; deba@1032: deba@1032: MapReader(Map& _map, const Reader& _reader) deba@1032: : map(_map), reader(_reader) {} deba@1032: deba@1032: deba@1032: virtual void read(istream& is, const Item& item) { deba@1032: typename Reader::Value value; deba@1032: reader.read(is, value); deba@1032: map.set(item, value); deba@1032: } deba@1032: }; deba@1032: deba@1032: typedef std::map* > NodeReaders; deba@1032: NodeReaders node_readers; deba@1032: deba@1032: typedef std::map* > EdgeReaders; deba@1032: EdgeReaders edge_readers; deba@1032: deba@1032: }; deba@1032: deba@1032: }