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