/* -*- C++ -*- * src/lemon/graph_reader.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 Map utilities. #include #include #include #include #include /// \todo fix exceptions namespace lemon { struct DefaultReaderTraits { template struct Reader { typedef _Value Value; void read(std::istream& is, Value& value) { is >> value; } }; template struct Skipper { typedef _Value Value; void read(std::istream& is) { Value tmp; is >> tmp; } }; struct DefaultSkipper { void read(std::istream& is) { std::string tmp; is >> tmp; } }; }; class IOException { virtual string message() = 0; }; class FileReaderException { virtual int getLine() = 0; }; template class GraphReader { public: typedef _Graph Graph; typedef typename Graph::Node Node; typedef typename Graph::Edge Edge; typedef _ReaderTraits ReaderTraits; GraphReader(std::istream& _is, Graph& _graph) : is(_is), graph(_graph) {} template GraphReader& readNodeMap(std::string name, Map& map, const typename ReaderTraits::template Reader& reader = typename ReaderTraits::template Reader()) { return readNodeMap >(name, map, reader); } template GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) { node_readers.insert(make_pair(name, new MapReader(map, reader))); return *this; } template GraphReader& readEdgeMap(std::string name, Map& map, const typename ReaderTraits::template Reader& reader = typename ReaderTraits::template Reader()) { return readEdgeMap >(name, map, reader); } template GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) { edge_readers.insert(make_pair(name, new MapReader(map, reader))); return *this; } void read() { int line_num = 0; readNodeSet(line_num); readEdgeSet(line_num); { std::string line = readNotEmptyLine(is, line_num); } } private: void readNodeSet(int& line_num) { int n = 0; { std::string line = readNotEmptyLine(is, line_num); } std::vector*> index; { std::string line = readNotEmptyLine(is, line_num); std::string id; std::istringstream ls(line); while (ls >> id) { typename map* >::iterator it = node_readers.find(id); if (it != node_readers.end()) { index.push_back(it->second); } else { index.push_back(0); } ++n; } } std::string line; while (line = readNotEmptyLine(is, line_num), line[0] != '@') { Node node = graph.addNode(); std::istringstream ls(line); for (int i = 0; i < n; ++i) { if (index[i] != 0) { index[i]->read(ls, node); } else { default_skipper.read(ls); } } } } void readEdgeSet(int& line_num) { } std::string readNotEmptyLine(std::istream& is, int& line_num) { std::string line; while (++line_num, getline(is, line)) { int vi = line.find_first_not_of(" \t"); if (vi != string::npos && line[vi] != '#') { return line.substr(vi); } } throw Exception(); } istream& is; Graph& graph; typename ReaderTraits::DefaultSkipper default_skipper; template class MapReaderBase { public: typedef _Item Item; virtual void read(istream& is, const Item& item) = 0; }; template class MapReader : public MapReaderBase<_Item> { public: typedef _Map Map; typedef _Reader Reader; typedef _Item Item; Map& map; Reader reader; MapReader(Map& _map, const Reader& _reader) : map(_map), reader(_reader) {} virtual void read(istream& is, const Item& item) { typename Reader::Value value; reader.read(is, value); map.set(item, value); } }; typedef std::map* > NodeReaders; NodeReaders node_readers; typedef std::map* > EdgeReaders; EdgeReaders edge_readers; }; }