|
1 /* -*- C++ -*- |
|
2 * src/lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library |
|
3 * |
|
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
|
5 * (Egervary Combinatorial Optimization Research Group, EGRES). |
|
6 * |
|
7 * Permission to use, modify and distribute this software is granted |
|
8 * provided that this copyright notice appears in all copies. For |
|
9 * precise terms see the accompanying LICENSE file. |
|
10 * |
|
11 * This software is provided "AS IS" with no warranty of any kind, |
|
12 * express or implied, and with no claim as to its suitability for any |
|
13 * purpose. |
|
14 * |
|
15 */ |
|
16 |
|
17 ///\ingroup gio |
|
18 ///\file |
|
19 ///\brief Map utilities. |
|
20 |
|
21 #include <iostream> |
|
22 #include <sstream> |
|
23 |
|
24 #include <map> |
|
25 #include <vector> |
|
26 |
|
27 #include <lemon/error.h> |
|
28 |
|
29 /// \todo fix exceptions |
|
30 |
|
31 |
|
32 namespace lemon { |
|
33 |
|
34 struct DefaultReaderTraits { |
|
35 |
|
36 template <typename _Value> |
|
37 struct Reader { |
|
38 typedef _Value Value; |
|
39 void read(std::istream& is, Value& value) { |
|
40 is >> value; |
|
41 } |
|
42 }; |
|
43 |
|
44 template <typename _Value> |
|
45 struct Skipper { |
|
46 typedef _Value Value; |
|
47 void read(std::istream& is) { |
|
48 Value tmp; |
|
49 is >> tmp; |
|
50 } |
|
51 }; |
|
52 |
|
53 struct DefaultSkipper { |
|
54 void read(std::istream& is) { |
|
55 std::string tmp; |
|
56 is >> tmp; |
|
57 } |
|
58 }; |
|
59 }; |
|
60 |
|
61 class IOException { |
|
62 virtual string message() = 0; |
|
63 }; |
|
64 |
|
65 class FileReaderException { |
|
66 virtual int getLine() = 0; |
|
67 }; |
|
68 |
|
69 |
|
70 |
|
71 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> |
|
72 class GraphReader { |
|
73 |
|
74 public: |
|
75 |
|
76 typedef _Graph Graph; |
|
77 typedef typename Graph::Node Node; |
|
78 typedef typename Graph::Edge Edge; |
|
79 |
|
80 typedef _ReaderTraits ReaderTraits; |
|
81 |
|
82 |
|
83 GraphReader(std::istream& _is, Graph& _graph) : is(_is), graph(_graph) {} |
|
84 |
|
85 template <typename Map> |
|
86 GraphReader& readNodeMap(std::string name, Map& map, |
|
87 const typename ReaderTraits::template Reader<typename Map::Value>& reader = |
|
88 typename ReaderTraits::template Reader<typename Map::Value>()) { |
|
89 return readNodeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader); |
|
90 } |
|
91 |
|
92 template <typename Map, typename Reader> |
|
93 GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) { |
|
94 node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader))); |
|
95 return *this; |
|
96 } |
|
97 |
|
98 template <typename Map> |
|
99 GraphReader& readEdgeMap(std::string name, Map& map, |
|
100 const typename ReaderTraits::template Reader<typename Map::Value>& reader = |
|
101 typename ReaderTraits::template Reader<typename Map::Value>()) { |
|
102 return readEdgeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader); |
|
103 } |
|
104 |
|
105 template <typename Map, typename Reader> |
|
106 GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) { |
|
107 edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader))); |
|
108 return *this; |
|
109 } |
|
110 |
|
111 void read() { |
|
112 int line_num = 0; |
|
113 readNodeSet(line_num); |
|
114 readEdgeSet(line_num); |
|
115 { |
|
116 std::string line = readNotEmptyLine(is, line_num); |
|
117 } |
|
118 } |
|
119 |
|
120 private: |
|
121 |
|
122 void readNodeSet(int& line_num) { |
|
123 int n = 0; |
|
124 { |
|
125 std::string line = readNotEmptyLine(is, line_num); |
|
126 } |
|
127 std::vector<MapReaderBase<Node>*> index; |
|
128 { |
|
129 std::string line = readNotEmptyLine(is, line_num); |
|
130 std::string id; |
|
131 std::istringstream ls(line); |
|
132 while (ls >> id) { |
|
133 typename map<std::string, MapReaderBase<Node>* >::iterator it = node_readers.find(id); |
|
134 if (it != node_readers.end()) { |
|
135 index.push_back(it->second); |
|
136 } else { |
|
137 index.push_back(0); |
|
138 } |
|
139 ++n; |
|
140 } |
|
141 } |
|
142 std::string line; |
|
143 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
|
144 Node node = graph.addNode(); |
|
145 std::istringstream ls(line); |
|
146 for (int i = 0; i < n; ++i) { |
|
147 if (index[i] != 0) { |
|
148 index[i]->read(ls, node); |
|
149 } else { |
|
150 default_skipper.read(ls); |
|
151 } |
|
152 } |
|
153 } |
|
154 } |
|
155 |
|
156 void readEdgeSet(int& line_num) { |
|
157 |
|
158 } |
|
159 |
|
160 std::string readNotEmptyLine(std::istream& is, int& line_num) { |
|
161 std::string line; |
|
162 while (++line_num, getline(is, line)) { |
|
163 int vi = line.find_first_not_of(" \t"); |
|
164 if (vi != string::npos && line[vi] != '#') { |
|
165 return line.substr(vi); |
|
166 } |
|
167 } |
|
168 throw Exception(); |
|
169 } |
|
170 |
|
171 istream& is; |
|
172 Graph& graph; |
|
173 |
|
174 typename ReaderTraits::DefaultSkipper default_skipper; |
|
175 |
|
176 template <typename _Item> |
|
177 class MapReaderBase { |
|
178 public: |
|
179 typedef _Item Item; |
|
180 virtual void read(istream& is, const Item& item) = 0; |
|
181 }; |
|
182 |
|
183 template <typename _Item, typename _Map, typename _Reader> |
|
184 class MapReader : public MapReaderBase<_Item> { |
|
185 public: |
|
186 typedef _Map Map; |
|
187 typedef _Reader Reader; |
|
188 typedef _Item Item; |
|
189 |
|
190 Map& map; |
|
191 Reader reader; |
|
192 |
|
193 MapReader(Map& _map, const Reader& _reader) |
|
194 : map(_map), reader(_reader) {} |
|
195 |
|
196 |
|
197 virtual void read(istream& is, const Item& item) { |
|
198 typename Reader::Value value; |
|
199 reader.read(is, value); |
|
200 map.set(item, value); |
|
201 } |
|
202 }; |
|
203 |
|
204 typedef std::map<std::string, MapReaderBase<Node>* > NodeReaders; |
|
205 NodeReaders node_readers; |
|
206 |
|
207 typedef std::map<std::string, MapReaderBase<Edge>* > EdgeReaders; |
|
208 EdgeReaders edge_readers; |
|
209 |
|
210 }; |
|
211 |
|
212 } |