lemongraph 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +8 -0
  3. data/LICENSE +674 -0
  4. data/README.md +6 -0
  5. data/ext/lemon-1.3.1/AUTHORS +26 -0
  6. data/ext/lemon-1.3.1/CMakeLists.txt +371 -0
  7. data/ext/lemon-1.3.1/INSTALL +167 -0
  8. data/ext/lemon-1.3.1/LICENSE +32 -0
  9. data/ext/lemon-1.3.1/NEWS +337 -0
  10. data/ext/lemon-1.3.1/README +50 -0
  11. data/ext/lemon-1.3.1/cmake/FindCOIN.cmake +110 -0
  12. data/ext/lemon-1.3.1/cmake/FindGLPK.cmake +55 -0
  13. data/ext/lemon-1.3.1/cmake/FindGhostscript.cmake +10 -0
  14. data/ext/lemon-1.3.1/cmake/FindILOG.cmake +102 -0
  15. data/ext/lemon-1.3.1/cmake/FindSOPLEX.cmake +23 -0
  16. data/ext/lemon-1.3.1/cmake/LEMONConfig.cmake.in +13 -0
  17. data/ext/lemon-1.3.1/cmake/nsis/lemon.ico +0 -0
  18. data/ext/lemon-1.3.1/cmake/nsis/uninstall.ico +0 -0
  19. data/ext/lemon-1.3.1/cmake/version.cmake +1 -0
  20. data/ext/lemon-1.3.1/cmake/version.cmake.in +1 -0
  21. data/ext/lemon-1.3.1/contrib/CMakeLists.txt +19 -0
  22. data/ext/lemon-1.3.1/lemon/CMakeLists.txt +91 -0
  23. data/ext/lemon-1.3.1/lemon/adaptors.h +3638 -0
  24. data/ext/lemon-1.3.1/lemon/arg_parser.cc +474 -0
  25. data/ext/lemon-1.3.1/lemon/arg_parser.h +440 -0
  26. data/ext/lemon-1.3.1/lemon/assert.h +214 -0
  27. data/ext/lemon-1.3.1/lemon/base.cc +37 -0
  28. data/ext/lemon-1.3.1/lemon/bellman_ford.h +1116 -0
  29. data/ext/lemon-1.3.1/lemon/bfs.h +1754 -0
  30. data/ext/lemon-1.3.1/lemon/bin_heap.h +347 -0
  31. data/ext/lemon-1.3.1/lemon/binomial_heap.h +445 -0
  32. data/ext/lemon-1.3.1/lemon/bits/alteration_notifier.h +472 -0
  33. data/ext/lemon-1.3.1/lemon/bits/array_map.h +351 -0
  34. data/ext/lemon-1.3.1/lemon/bits/bezier.h +174 -0
  35. data/ext/lemon-1.3.1/lemon/bits/default_map.h +182 -0
  36. data/ext/lemon-1.3.1/lemon/bits/edge_set_extender.h +627 -0
  37. data/ext/lemon-1.3.1/lemon/bits/enable_if.h +131 -0
  38. data/ext/lemon-1.3.1/lemon/bits/graph_adaptor_extender.h +401 -0
  39. data/ext/lemon-1.3.1/lemon/bits/graph_extender.h +1332 -0
  40. data/ext/lemon-1.3.1/lemon/bits/lock.h +65 -0
  41. data/ext/lemon-1.3.1/lemon/bits/map_extender.h +332 -0
  42. data/ext/lemon-1.3.1/lemon/bits/path_dump.h +177 -0
  43. data/ext/lemon-1.3.1/lemon/bits/solver_bits.h +194 -0
  44. data/ext/lemon-1.3.1/lemon/bits/traits.h +388 -0
  45. data/ext/lemon-1.3.1/lemon/bits/variant.h +494 -0
  46. data/ext/lemon-1.3.1/lemon/bits/vector_map.h +244 -0
  47. data/ext/lemon-1.3.1/lemon/bits/windows.cc +166 -0
  48. data/ext/lemon-1.3.1/lemon/bits/windows.h +44 -0
  49. data/ext/lemon-1.3.1/lemon/bucket_heap.h +594 -0
  50. data/ext/lemon-1.3.1/lemon/capacity_scaling.h +1014 -0
  51. data/ext/lemon-1.3.1/lemon/cbc.cc +460 -0
  52. data/ext/lemon-1.3.1/lemon/cbc.h +129 -0
  53. data/ext/lemon-1.3.1/lemon/christofides_tsp.h +254 -0
  54. data/ext/lemon-1.3.1/lemon/circulation.h +807 -0
  55. data/ext/lemon-1.3.1/lemon/clp.cc +464 -0
  56. data/ext/lemon-1.3.1/lemon/clp.h +164 -0
  57. data/ext/lemon-1.3.1/lemon/color.cc +44 -0
  58. data/ext/lemon-1.3.1/lemon/color.h +204 -0
  59. data/ext/lemon-1.3.1/lemon/concept_check.h +77 -0
  60. data/ext/lemon-1.3.1/lemon/concepts/bpgraph.h +1029 -0
  61. data/ext/lemon-1.3.1/lemon/concepts/digraph.h +491 -0
  62. data/ext/lemon-1.3.1/lemon/concepts/graph.h +788 -0
  63. data/ext/lemon-1.3.1/lemon/concepts/graph_components.h +2134 -0
  64. data/ext/lemon-1.3.1/lemon/concepts/heap.h +324 -0
  65. data/ext/lemon-1.3.1/lemon/concepts/maps.h +223 -0
  66. data/ext/lemon-1.3.1/lemon/concepts/path.h +312 -0
  67. data/ext/lemon-1.3.1/lemon/config.h.in +22 -0
  68. data/ext/lemon-1.3.1/lemon/connectivity.h +1688 -0
  69. data/ext/lemon-1.3.1/lemon/core.h +2506 -0
  70. data/ext/lemon-1.3.1/lemon/cost_scaling.h +1607 -0
  71. data/ext/lemon-1.3.1/lemon/counter.h +249 -0
  72. data/ext/lemon-1.3.1/lemon/cplex.cc +994 -0
  73. data/ext/lemon-1.3.1/lemon/cplex.h +292 -0
  74. data/ext/lemon-1.3.1/lemon/cycle_canceling.h +1230 -0
  75. data/ext/lemon-1.3.1/lemon/dfs.h +1637 -0
  76. data/ext/lemon-1.3.1/lemon/dheap.h +352 -0
  77. data/ext/lemon-1.3.1/lemon/dijkstra.h +1303 -0
  78. data/ext/lemon-1.3.1/lemon/dim2.h +726 -0
  79. data/ext/lemon-1.3.1/lemon/dimacs.h +448 -0
  80. data/ext/lemon-1.3.1/lemon/edge_set.h +1420 -0
  81. data/ext/lemon-1.3.1/lemon/edmonds_karp.h +556 -0
  82. data/ext/lemon-1.3.1/lemon/elevator.h +982 -0
  83. data/ext/lemon-1.3.1/lemon/error.h +276 -0
  84. data/ext/lemon-1.3.1/lemon/euler.h +287 -0
  85. data/ext/lemon-1.3.1/lemon/fib_heap.h +475 -0
  86. data/ext/lemon-1.3.1/lemon/fractional_matching.h +2139 -0
  87. data/ext/lemon-1.3.1/lemon/full_graph.h +1082 -0
  88. data/ext/lemon-1.3.1/lemon/glpk.cc +1012 -0
  89. data/ext/lemon-1.3.1/lemon/glpk.h +263 -0
  90. data/ext/lemon-1.3.1/lemon/gomory_hu.h +568 -0
  91. data/ext/lemon-1.3.1/lemon/graph_to_eps.h +1186 -0
  92. data/ext/lemon-1.3.1/lemon/greedy_tsp.h +251 -0
  93. data/ext/lemon-1.3.1/lemon/grid_graph.h +699 -0
  94. data/ext/lemon-1.3.1/lemon/grosso_locatelli_pullan_mc.h +840 -0
  95. data/ext/lemon-1.3.1/lemon/hao_orlin.h +1015 -0
  96. data/ext/lemon-1.3.1/lemon/hartmann_orlin_mmc.h +654 -0
  97. data/ext/lemon-1.3.1/lemon/howard_mmc.h +651 -0
  98. data/ext/lemon-1.3.1/lemon/hypercube_graph.h +459 -0
  99. data/ext/lemon-1.3.1/lemon/insertion_tsp.h +533 -0
  100. data/ext/lemon-1.3.1/lemon/karp_mmc.h +590 -0
  101. data/ext/lemon-1.3.1/lemon/kruskal.h +324 -0
  102. data/ext/lemon-1.3.1/lemon/lemon.pc.in +10 -0
  103. data/ext/lemon-1.3.1/lemon/lgf_reader.h +3854 -0
  104. data/ext/lemon-1.3.1/lemon/lgf_writer.h +2687 -0
  105. data/ext/lemon-1.3.1/lemon/list_graph.h +2510 -0
  106. data/ext/lemon-1.3.1/lemon/lp.h +95 -0
  107. data/ext/lemon-1.3.1/lemon/lp_base.cc +30 -0
  108. data/ext/lemon-1.3.1/lemon/lp_base.h +2147 -0
  109. data/ext/lemon-1.3.1/lemon/lp_skeleton.cc +143 -0
  110. data/ext/lemon-1.3.1/lemon/lp_skeleton.h +234 -0
  111. data/ext/lemon-1.3.1/lemon/maps.h +4057 -0
  112. data/ext/lemon-1.3.1/lemon/matching.h +3505 -0
  113. data/ext/lemon-1.3.1/lemon/math.h +77 -0
  114. data/ext/lemon-1.3.1/lemon/max_cardinality_search.h +794 -0
  115. data/ext/lemon-1.3.1/lemon/min_cost_arborescence.h +808 -0
  116. data/ext/lemon-1.3.1/lemon/nagamochi_ibaraki.h +702 -0
  117. data/ext/lemon-1.3.1/lemon/nauty_reader.h +113 -0
  118. data/ext/lemon-1.3.1/lemon/nearest_neighbor_tsp.h +238 -0
  119. data/ext/lemon-1.3.1/lemon/network_simplex.h +1659 -0
  120. data/ext/lemon-1.3.1/lemon/opt2_tsp.h +367 -0
  121. data/ext/lemon-1.3.1/lemon/pairing_heap.h +474 -0
  122. data/ext/lemon-1.3.1/lemon/path.h +1164 -0
  123. data/ext/lemon-1.3.1/lemon/planarity.h +2754 -0
  124. data/ext/lemon-1.3.1/lemon/preflow.h +985 -0
  125. data/ext/lemon-1.3.1/lemon/quad_heap.h +343 -0
  126. data/ext/lemon-1.3.1/lemon/radix_heap.h +438 -0
  127. data/ext/lemon-1.3.1/lemon/radix_sort.h +487 -0
  128. data/ext/lemon-1.3.1/lemon/random.cc +29 -0
  129. data/ext/lemon-1.3.1/lemon/random.h +1005 -0
  130. data/ext/lemon-1.3.1/lemon/smart_graph.h +1344 -0
  131. data/ext/lemon-1.3.1/lemon/soplex.cc +465 -0
  132. data/ext/lemon-1.3.1/lemon/soplex.h +158 -0
  133. data/ext/lemon-1.3.1/lemon/static_graph.h +476 -0
  134. data/ext/lemon-1.3.1/lemon/suurballe.h +776 -0
  135. data/ext/lemon-1.3.1/lemon/time_measure.h +610 -0
  136. data/ext/lemon-1.3.1/lemon/tolerance.h +242 -0
  137. data/ext/lemon-1.3.1/lemon/unionfind.h +1824 -0
  138. data/ext/lemon-1.3.1/scripts/unify-sources.sh +390 -0
  139. data/ext/lemon-1.3.1/scripts/valgrind-wrapper.sh +22 -0
  140. data/ext/lemongraph/arc_map.cc +1007 -0
  141. data/ext/lemongraph/digraph.cc +282 -0
  142. data/ext/lemongraph/digraph_arc.cc +153 -0
  143. data/ext/lemongraph/digraph_node.cc +277 -0
  144. data/ext/lemongraph/edge_map.cc +770 -0
  145. data/ext/lemongraph/extconf.rb +53 -0
  146. data/ext/lemongraph/graph.cc +351 -0
  147. data/ext/lemongraph/graph_arc.cc +95 -0
  148. data/ext/lemongraph/graph_edge.cc +153 -0
  149. data/ext/lemongraph/graph_item.cc +76 -0
  150. data/ext/lemongraph/graph_node.cc +321 -0
  151. data/ext/lemongraph/lemongraph.cc +260 -0
  152. data/ext/lemongraph/lemongraph.hh +295 -0
  153. data/ext/lemongraph/lemongraph.map +6 -0
  154. data/ext/lemongraph/lemongraph_export.hh +31 -0
  155. data/ext/lemongraph/node_map.cc +1011 -0
  156. data/lemongraph.gemspec +176 -0
  157. data/lib/lemongraph/graphviz.rb +240 -0
  158. data/lib/lemongraph/version.rb +4 -0
  159. data/lib/lemongraph.rb +21 -0
  160. data/samples/lemondeps.rb +38 -0
  161. metadata +202 -0
@@ -0,0 +1,3854 @@
1
+ /* -*- mode: C++; indent-tabs-mode: nil; -*-
2
+ *
3
+ * This file is a part of LEMON, a generic C++ optimization library.
4
+ *
5
+ * Copyright (C) 2003-2013
6
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
+ *
9
+ * Permission to use, modify and distribute this software is granted
10
+ * provided that this copyright notice appears in all copies. For
11
+ * precise terms see the accompanying LICENSE file.
12
+ *
13
+ * This software is provided "AS IS" with no warranty of any kind,
14
+ * express or implied, and with no claim as to its suitability for any
15
+ * purpose.
16
+ *
17
+ */
18
+
19
+ ///\ingroup lemon_io
20
+ ///\file
21
+ ///\brief \ref lgf-format "LEMON Graph Format" reader.
22
+
23
+
24
+ #ifndef LEMON_LGF_READER_H
25
+ #define LEMON_LGF_READER_H
26
+
27
+ #include <iostream>
28
+ #include <fstream>
29
+ #include <sstream>
30
+
31
+ #include <set>
32
+ #include <map>
33
+
34
+ #include <lemon/core.h>
35
+
36
+ #include <lemon/lgf_writer.h>
37
+
38
+ #include <lemon/concept_check.h>
39
+ #include <lemon/concepts/maps.h>
40
+
41
+ namespace lemon {
42
+
43
+ namespace _reader_bits {
44
+
45
+ template <typename Value>
46
+ struct DefaultConverter {
47
+ Value operator()(const std::string& str) {
48
+ std::istringstream is(str);
49
+ Value value;
50
+ if (!(is >> value)) {
51
+ throw FormatError("Cannot read token");
52
+ }
53
+
54
+ char c;
55
+ if (is >> std::ws >> c) {
56
+ throw FormatError("Remaining characters in token");
57
+ }
58
+ return value;
59
+ }
60
+ };
61
+
62
+ template <>
63
+ struct DefaultConverter<std::string> {
64
+ std::string operator()(const std::string& str) {
65
+ return str;
66
+ }
67
+ };
68
+
69
+ template <typename _Item>
70
+ class MapStorageBase {
71
+ public:
72
+ typedef _Item Item;
73
+
74
+ public:
75
+ MapStorageBase() {}
76
+ virtual ~MapStorageBase() {}
77
+
78
+ virtual void set(const Item& item, const std::string& value) = 0;
79
+
80
+ };
81
+
82
+ template <typename _Item, typename _Map,
83
+ typename _Converter = DefaultConverter<typename _Map::Value> >
84
+ class MapStorage : public MapStorageBase<_Item> {
85
+ public:
86
+ typedef _Map Map;
87
+ typedef _Converter Converter;
88
+ typedef _Item Item;
89
+
90
+ private:
91
+ Map& _map;
92
+ Converter _converter;
93
+
94
+ public:
95
+ MapStorage(Map& map, const Converter& converter = Converter())
96
+ : _map(map), _converter(converter) {}
97
+ virtual ~MapStorage() {}
98
+
99
+ virtual void set(const Item& item ,const std::string& value) {
100
+ _map.set(item, _converter(value));
101
+ }
102
+ };
103
+
104
+ template <typename _GR, bool _dir, typename _Map,
105
+ typename _Converter = DefaultConverter<typename _Map::Value> >
106
+ class GraphArcMapStorage : public MapStorageBase<typename _GR::Edge> {
107
+ public:
108
+ typedef _Map Map;
109
+ typedef _Converter Converter;
110
+ typedef _GR GR;
111
+ typedef typename GR::Edge Item;
112
+ static const bool dir = _dir;
113
+
114
+ private:
115
+ const GR& _graph;
116
+ Map& _map;
117
+ Converter _converter;
118
+
119
+ public:
120
+ GraphArcMapStorage(const GR& graph, Map& map,
121
+ const Converter& converter = Converter())
122
+ : _graph(graph), _map(map), _converter(converter) {}
123
+ virtual ~GraphArcMapStorage() {}
124
+
125
+ virtual void set(const Item& item ,const std::string& value) {
126
+ _map.set(_graph.direct(item, dir), _converter(value));
127
+ }
128
+ };
129
+
130
+ class ValueStorageBase {
131
+ public:
132
+ ValueStorageBase() {}
133
+ virtual ~ValueStorageBase() {}
134
+
135
+ virtual void set(const std::string&) = 0;
136
+ };
137
+
138
+ template <typename _Value, typename _Converter = DefaultConverter<_Value> >
139
+ class ValueStorage : public ValueStorageBase {
140
+ public:
141
+ typedef _Value Value;
142
+ typedef _Converter Converter;
143
+
144
+ private:
145
+ Value& _value;
146
+ Converter _converter;
147
+
148
+ public:
149
+ ValueStorage(Value& value, const Converter& converter = Converter())
150
+ : _value(value), _converter(converter) {}
151
+
152
+ virtual void set(const std::string& value) {
153
+ _value = _converter(value);
154
+ }
155
+ };
156
+
157
+ template <typename Value,
158
+ typename Map = std::map<std::string, Value> >
159
+ struct MapLookUpConverter {
160
+ const Map& _map;
161
+
162
+ MapLookUpConverter(const Map& map)
163
+ : _map(map) {}
164
+
165
+ Value operator()(const std::string& str) {
166
+ typename Map::const_iterator it = _map.find(str);
167
+ if (it == _map.end()) {
168
+ std::ostringstream msg;
169
+ msg << "Item not found: " << str;
170
+ throw FormatError(msg.str());
171
+ }
172
+ return it->second;
173
+ }
174
+ };
175
+
176
+ template <typename Value,
177
+ typename Map1 = std::map<std::string, Value>,
178
+ typename Map2 = std::map<std::string, Value> >
179
+ struct DoubleMapLookUpConverter {
180
+ const Map1& _map1;
181
+ const Map2& _map2;
182
+
183
+ DoubleMapLookUpConverter(const Map1& map1, const Map2& map2)
184
+ : _map1(map1), _map2(map2) {}
185
+
186
+ Value operator()(const std::string& str) {
187
+ typename Map1::const_iterator it1 = _map1.find(str);
188
+ typename Map2::const_iterator it2 = _map2.find(str);
189
+ if (it1 == _map1.end()) {
190
+ if (it2 == _map2.end()) {
191
+ std::ostringstream msg;
192
+ msg << "Item not found: " << str;
193
+ throw FormatError(msg.str());
194
+ } else {
195
+ return it2->second;
196
+ }
197
+ } else {
198
+ if (it2 == _map2.end()) {
199
+ return it1->second;
200
+ } else {
201
+ std::ostringstream msg;
202
+ msg << "Item is ambigous: " << str;
203
+ throw FormatError(msg.str());
204
+ }
205
+ }
206
+ }
207
+ };
208
+
209
+ template <typename GR>
210
+ struct GraphArcLookUpConverter {
211
+ const GR& _graph;
212
+ const std::map<std::string, typename GR::Edge>& _map;
213
+
214
+ GraphArcLookUpConverter(const GR& graph,
215
+ const std::map<std::string,
216
+ typename GR::Edge>& map)
217
+ : _graph(graph), _map(map) {}
218
+
219
+ typename GR::Arc operator()(const std::string& str) {
220
+ if (str.empty() || (str[0] != '+' && str[0] != '-')) {
221
+ throw FormatError("Item must start with '+' or '-'");
222
+ }
223
+ typename std::map<std::string, typename GR::Edge>
224
+ ::const_iterator it = _map.find(str.substr(1));
225
+ if (it == _map.end()) {
226
+ throw FormatError("Item not found");
227
+ }
228
+ return _graph.direct(it->second, str[0] == '+');
229
+ }
230
+ };
231
+
232
+ inline bool isWhiteSpace(char c) {
233
+ return c == ' ' || c == '\t' || c == '\v' ||
234
+ c == '\n' || c == '\r' || c == '\f';
235
+ }
236
+
237
+ inline bool isOct(char c) {
238
+ return '0' <= c && c <='7';
239
+ }
240
+
241
+ inline int valueOct(char c) {
242
+ LEMON_ASSERT(isOct(c), "The character is not octal.");
243
+ return c - '0';
244
+ }
245
+
246
+ inline bool isHex(char c) {
247
+ return ('0' <= c && c <= '9') ||
248
+ ('a' <= c && c <= 'z') ||
249
+ ('A' <= c && c <= 'Z');
250
+ }
251
+
252
+ inline int valueHex(char c) {
253
+ LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
254
+ if ('0' <= c && c <= '9') return c - '0';
255
+ if ('a' <= c && c <= 'z') return c - 'a' + 10;
256
+ return c - 'A' + 10;
257
+ }
258
+
259
+ inline bool isIdentifierFirstChar(char c) {
260
+ return ('a' <= c && c <= 'z') ||
261
+ ('A' <= c && c <= 'Z') || c == '_';
262
+ }
263
+
264
+ inline bool isIdentifierChar(char c) {
265
+ return isIdentifierFirstChar(c) ||
266
+ ('0' <= c && c <= '9');
267
+ }
268
+
269
+ inline char readEscape(std::istream& is) {
270
+ char c;
271
+ if (!is.get(c))
272
+ throw FormatError("Escape format error");
273
+
274
+ switch (c) {
275
+ case '\\':
276
+ return '\\';
277
+ case '\"':
278
+ return '\"';
279
+ case '\'':
280
+ return '\'';
281
+ case '\?':
282
+ return '\?';
283
+ case 'a':
284
+ return '\a';
285
+ case 'b':
286
+ return '\b';
287
+ case 'f':
288
+ return '\f';
289
+ case 'n':
290
+ return '\n';
291
+ case 'r':
292
+ return '\r';
293
+ case 't':
294
+ return '\t';
295
+ case 'v':
296
+ return '\v';
297
+ case 'x':
298
+ {
299
+ int code;
300
+ if (!is.get(c) || !isHex(c))
301
+ throw FormatError("Escape format error");
302
+ else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
303
+ else code = code * 16 + valueHex(c);
304
+ return code;
305
+ }
306
+ default:
307
+ {
308
+ int code;
309
+ if (!isOct(c))
310
+ throw FormatError("Escape format error");
311
+ else if (code = valueOct(c), !is.get(c) || !isOct(c))
312
+ is.putback(c);
313
+ else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
314
+ is.putback(c);
315
+ else code = code * 8 + valueOct(c);
316
+ return code;
317
+ }
318
+ }
319
+ }
320
+
321
+ inline std::istream& readToken(std::istream& is, std::string& str) {
322
+ std::ostringstream os;
323
+
324
+ char c;
325
+ is >> std::ws;
326
+
327
+ if (!is.get(c))
328
+ return is;
329
+
330
+ if (c == '\"') {
331
+ while (is.get(c) && c != '\"') {
332
+ if (c == '\\')
333
+ c = readEscape(is);
334
+ os << c;
335
+ }
336
+ if (!is)
337
+ throw FormatError("Quoted format error");
338
+ } else {
339
+ is.putback(c);
340
+ while (is.get(c) && !isWhiteSpace(c)) {
341
+ if (c == '\\')
342
+ c = readEscape(is);
343
+ os << c;
344
+ }
345
+ if (!is) {
346
+ is.clear();
347
+ } else {
348
+ is.putback(c);
349
+ }
350
+ }
351
+ str = os.str();
352
+ return is;
353
+ }
354
+
355
+ class Section {
356
+ public:
357
+ virtual ~Section() {}
358
+ virtual void process(std::istream& is, int& line_num) = 0;
359
+ };
360
+
361
+ template <typename Functor>
362
+ class LineSection : public Section {
363
+ private:
364
+
365
+ Functor _functor;
366
+
367
+ public:
368
+
369
+ LineSection(const Functor& functor) : _functor(functor) {}
370
+ virtual ~LineSection() {}
371
+
372
+ virtual void process(std::istream& is, int& line_num) {
373
+ char c;
374
+ std::string line;
375
+ while (is.get(c) && c != '@') {
376
+ if (c == '\n') {
377
+ ++line_num;
378
+ } else if (c == '#') {
379
+ getline(is, line);
380
+ ++line_num;
381
+ } else if (!isWhiteSpace(c)) {
382
+ is.putback(c);
383
+ getline(is, line);
384
+ _functor(line);
385
+ ++line_num;
386
+ }
387
+ }
388
+ if (is) is.putback(c);
389
+ else if (is.eof()) is.clear();
390
+ }
391
+ };
392
+
393
+ template <typename Functor>
394
+ class StreamSection : public Section {
395
+ private:
396
+
397
+ Functor _functor;
398
+
399
+ public:
400
+
401
+ StreamSection(const Functor& functor) : _functor(functor) {}
402
+ virtual ~StreamSection() {}
403
+
404
+ virtual void process(std::istream& is, int& line_num) {
405
+ _functor(is, line_num);
406
+ char c;
407
+ std::string line;
408
+ while (is.get(c) && c != '@') {
409
+ if (c == '\n') {
410
+ ++line_num;
411
+ } else if (!isWhiteSpace(c)) {
412
+ getline(is, line);
413
+ ++line_num;
414
+ }
415
+ }
416
+ if (is) is.putback(c);
417
+ else if (is.eof()) is.clear();
418
+ }
419
+ };
420
+
421
+ }
422
+
423
+ template <typename DGR>
424
+ class DigraphReader;
425
+
426
+ template <typename TDGR>
427
+ DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is = std::cin);
428
+ template <typename TDGR>
429
+ DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn);
430
+ template <typename TDGR>
431
+ DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
432
+
433
+ /// \ingroup lemon_io
434
+ ///
435
+ /// \brief \ref lgf-format "LGF" reader for directed graphs
436
+ ///
437
+ /// This utility reads an \ref lgf-format "LGF" file.
438
+ ///
439
+ /// The reading method does a batch processing. The user creates a
440
+ /// reader object, then various reading rules can be added to the
441
+ /// reader, and eventually the reading is executed with the \c run()
442
+ /// member function. A map reading rule can be added to the reader
443
+ /// with the \c nodeMap() or \c arcMap() members. An optional
444
+ /// converter parameter can also be added as a standard functor
445
+ /// converting from \c std::string to the value type of the map. If it
446
+ /// is set, it will determine how the tokens in the file should be
447
+ /// converted to the value type of the map. If the functor is not set,
448
+ /// then a default conversion will be used. One map can be read into
449
+ /// multiple map objects at the same time. The \c attribute(), \c
450
+ /// node() and \c arc() functions are used to add attribute reading
451
+ /// rules.
452
+ ///
453
+ ///\code
454
+ /// DigraphReader<DGR>(digraph, std::cin).
455
+ /// nodeMap("coordinates", coord_map).
456
+ /// arcMap("capacity", cap_map).
457
+ /// node("source", src).
458
+ /// node("target", trg).
459
+ /// attribute("caption", caption).
460
+ /// run();
461
+ ///\endcode
462
+ ///
463
+ /// By default, the reader uses the first section in the file of the
464
+ /// proper type. If a section has an optional name, then it can be
465
+ /// selected for reading by giving an optional name parameter to the
466
+ /// \c nodes(), \c arcs() or \c attributes() functions.
467
+ ///
468
+ /// The \c useNodes() and \c useArcs() functions are used to tell the reader
469
+ /// that the nodes or arcs should not be constructed (added to the
470
+ /// graph) during the reading, but instead the label map of the items
471
+ /// are given as a parameter of these functions. An
472
+ /// application of these functions is multipass reading, which is
473
+ /// important if two \c \@arcs sections must be read from the
474
+ /// file. In this case the first phase would read the node set and one
475
+ /// of the arc sets, while the second phase would read the second arc
476
+ /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
477
+ /// The previously read label node map should be passed to the \c
478
+ /// useNodes() functions. Another application of multipass reading when
479
+ /// paths are given as a node map or an arc map.
480
+ /// It is impossible to read this in
481
+ /// a single pass, because the arcs are not constructed when the node
482
+ /// maps are read.
483
+ template <typename DGR>
484
+ class DigraphReader {
485
+ public:
486
+
487
+ typedef DGR Digraph;
488
+
489
+ private:
490
+
491
+ TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
492
+
493
+ std::istream* _is;
494
+ bool local_is;
495
+ std::string _filename;
496
+
497
+ DGR& _digraph;
498
+
499
+ std::string _nodes_caption;
500
+ std::string _arcs_caption;
501
+ std::string _attributes_caption;
502
+
503
+ typedef std::map<std::string, Node> NodeIndex;
504
+ NodeIndex _node_index;
505
+ typedef std::map<std::string, Arc> ArcIndex;
506
+ ArcIndex _arc_index;
507
+
508
+ typedef std::vector<std::pair<std::string,
509
+ _reader_bits::MapStorageBase<Node>*> > NodeMaps;
510
+ NodeMaps _node_maps;
511
+
512
+ typedef std::vector<std::pair<std::string,
513
+ _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
514
+ ArcMaps _arc_maps;
515
+
516
+ typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
517
+ Attributes;
518
+ Attributes _attributes;
519
+
520
+ bool _use_nodes;
521
+ bool _use_arcs;
522
+
523
+ bool _skip_nodes;
524
+ bool _skip_arcs;
525
+
526
+ int line_num;
527
+ std::istringstream line;
528
+
529
+ public:
530
+
531
+ /// \brief Constructor
532
+ ///
533
+ /// Construct a directed graph reader, which reads from the given
534
+ /// input stream.
535
+ DigraphReader(DGR& digraph, std::istream& is = std::cin)
536
+ : _is(&is), local_is(false), _digraph(digraph),
537
+ _use_nodes(false), _use_arcs(false),
538
+ _skip_nodes(false), _skip_arcs(false) {}
539
+
540
+ /// \brief Constructor
541
+ ///
542
+ /// Construct a directed graph reader, which reads from the given
543
+ /// file.
544
+ DigraphReader(DGR& digraph, const std::string& fn)
545
+ : _is(new std::ifstream(fn.c_str())), local_is(true),
546
+ _filename(fn), _digraph(digraph),
547
+ _use_nodes(false), _use_arcs(false),
548
+ _skip_nodes(false), _skip_arcs(false) {
549
+ if (!(*_is)) {
550
+ delete _is;
551
+ throw IoError("Cannot open file", fn);
552
+ }
553
+ }
554
+
555
+ /// \brief Constructor
556
+ ///
557
+ /// Construct a directed graph reader, which reads from the given
558
+ /// file.
559
+ DigraphReader(DGR& digraph, const char* fn)
560
+ : _is(new std::ifstream(fn)), local_is(true),
561
+ _filename(fn), _digraph(digraph),
562
+ _use_nodes(false), _use_arcs(false),
563
+ _skip_nodes(false), _skip_arcs(false) {
564
+ if (!(*_is)) {
565
+ delete _is;
566
+ throw IoError("Cannot open file", fn);
567
+ }
568
+ }
569
+
570
+ /// \brief Destructor
571
+ ~DigraphReader() {
572
+ for (typename NodeMaps::iterator it = _node_maps.begin();
573
+ it != _node_maps.end(); ++it) {
574
+ delete it->second;
575
+ }
576
+
577
+ for (typename ArcMaps::iterator it = _arc_maps.begin();
578
+ it != _arc_maps.end(); ++it) {
579
+ delete it->second;
580
+ }
581
+
582
+ for (typename Attributes::iterator it = _attributes.begin();
583
+ it != _attributes.end(); ++it) {
584
+ delete it->second;
585
+ }
586
+
587
+ if (local_is) {
588
+ delete _is;
589
+ }
590
+
591
+ }
592
+
593
+ private:
594
+
595
+ template <typename TDGR>
596
+ friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is);
597
+ template <typename TDGR>
598
+ friend DigraphReader<TDGR> digraphReader(TDGR& digraph,
599
+ const std::string& fn);
600
+ template <typename TDGR>
601
+ friend DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
602
+
603
+ DigraphReader(DigraphReader& other)
604
+ : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
605
+ _use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
606
+ _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
607
+
608
+ other._is = 0;
609
+ other.local_is = false;
610
+
611
+ _node_index.swap(other._node_index);
612
+ _arc_index.swap(other._arc_index);
613
+
614
+ _node_maps.swap(other._node_maps);
615
+ _arc_maps.swap(other._arc_maps);
616
+ _attributes.swap(other._attributes);
617
+
618
+ _nodes_caption = other._nodes_caption;
619
+ _arcs_caption = other._arcs_caption;
620
+ _attributes_caption = other._attributes_caption;
621
+
622
+ }
623
+
624
+ DigraphReader& operator=(const DigraphReader&);
625
+
626
+ public:
627
+
628
+ /// \name Reading Rules
629
+ /// @{
630
+
631
+ /// \brief Node map reading rule
632
+ ///
633
+ /// Add a node map reading rule to the reader.
634
+ template <typename Map>
635
+ DigraphReader& nodeMap(const std::string& caption, Map& map) {
636
+ checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
637
+ _reader_bits::MapStorageBase<Node>* storage =
638
+ new _reader_bits::MapStorage<Node, Map>(map);
639
+ _node_maps.push_back(std::make_pair(caption, storage));
640
+ return *this;
641
+ }
642
+
643
+ /// \brief Node map reading rule
644
+ ///
645
+ /// Add a node map reading rule with specialized converter to the
646
+ /// reader.
647
+ template <typename Map, typename Converter>
648
+ DigraphReader& nodeMap(const std::string& caption, Map& map,
649
+ const Converter& converter = Converter()) {
650
+ checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
651
+ _reader_bits::MapStorageBase<Node>* storage =
652
+ new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
653
+ _node_maps.push_back(std::make_pair(caption, storage));
654
+ return *this;
655
+ }
656
+
657
+ /// \brief Arc map reading rule
658
+ ///
659
+ /// Add an arc map reading rule to the reader.
660
+ template <typename Map>
661
+ DigraphReader& arcMap(const std::string& caption, Map& map) {
662
+ checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
663
+ _reader_bits::MapStorageBase<Arc>* storage =
664
+ new _reader_bits::MapStorage<Arc, Map>(map);
665
+ _arc_maps.push_back(std::make_pair(caption, storage));
666
+ return *this;
667
+ }
668
+
669
+ /// \brief Arc map reading rule
670
+ ///
671
+ /// Add an arc map reading rule with specialized converter to the
672
+ /// reader.
673
+ template <typename Map, typename Converter>
674
+ DigraphReader& arcMap(const std::string& caption, Map& map,
675
+ const Converter& converter = Converter()) {
676
+ checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
677
+ _reader_bits::MapStorageBase<Arc>* storage =
678
+ new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
679
+ _arc_maps.push_back(std::make_pair(caption, storage));
680
+ return *this;
681
+ }
682
+
683
+ /// \brief Attribute reading rule
684
+ ///
685
+ /// Add an attribute reading rule to the reader.
686
+ template <typename Value>
687
+ DigraphReader& attribute(const std::string& caption, Value& value) {
688
+ _reader_bits::ValueStorageBase* storage =
689
+ new _reader_bits::ValueStorage<Value>(value);
690
+ _attributes.insert(std::make_pair(caption, storage));
691
+ return *this;
692
+ }
693
+
694
+ /// \brief Attribute reading rule
695
+ ///
696
+ /// Add an attribute reading rule with specialized converter to the
697
+ /// reader.
698
+ template <typename Value, typename Converter>
699
+ DigraphReader& attribute(const std::string& caption, Value& value,
700
+ const Converter& converter = Converter()) {
701
+ _reader_bits::ValueStorageBase* storage =
702
+ new _reader_bits::ValueStorage<Value, Converter>(value, converter);
703
+ _attributes.insert(std::make_pair(caption, storage));
704
+ return *this;
705
+ }
706
+
707
+ /// \brief Node reading rule
708
+ ///
709
+ /// Add a node reading rule to reader.
710
+ DigraphReader& node(const std::string& caption, Node& node) {
711
+ typedef _reader_bits::MapLookUpConverter<Node> Converter;
712
+ Converter converter(_node_index);
713
+ _reader_bits::ValueStorageBase* storage =
714
+ new _reader_bits::ValueStorage<Node, Converter>(node, converter);
715
+ _attributes.insert(std::make_pair(caption, storage));
716
+ return *this;
717
+ }
718
+
719
+ /// \brief Arc reading rule
720
+ ///
721
+ /// Add an arc reading rule to reader.
722
+ DigraphReader& arc(const std::string& caption, Arc& arc) {
723
+ typedef _reader_bits::MapLookUpConverter<Arc> Converter;
724
+ Converter converter(_arc_index);
725
+ _reader_bits::ValueStorageBase* storage =
726
+ new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
727
+ _attributes.insert(std::make_pair(caption, storage));
728
+ return *this;
729
+ }
730
+
731
+ /// @}
732
+
733
+ /// \name Select Section by Name
734
+ /// @{
735
+
736
+ /// \brief Set \c \@nodes section to be read
737
+ ///
738
+ /// Set \c \@nodes section to be read
739
+ DigraphReader& nodes(const std::string& caption) {
740
+ _nodes_caption = caption;
741
+ return *this;
742
+ }
743
+
744
+ /// \brief Set \c \@arcs section to be read
745
+ ///
746
+ /// Set \c \@arcs section to be read
747
+ DigraphReader& arcs(const std::string& caption) {
748
+ _arcs_caption = caption;
749
+ return *this;
750
+ }
751
+
752
+ /// \brief Set \c \@attributes section to be read
753
+ ///
754
+ /// Set \c \@attributes section to be read
755
+ DigraphReader& attributes(const std::string& caption) {
756
+ _attributes_caption = caption;
757
+ return *this;
758
+ }
759
+
760
+ /// @}
761
+
762
+ /// \name Using Previously Constructed Node or Arc Set
763
+ /// @{
764
+
765
+ /// \brief Use previously constructed node set
766
+ ///
767
+ /// Use previously constructed node set, and specify the node
768
+ /// label map.
769
+ template <typename Map>
770
+ DigraphReader& useNodes(const Map& map) {
771
+ checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
772
+ LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
773
+ _use_nodes = true;
774
+ _writer_bits::DefaultConverter<typename Map::Value> converter;
775
+ for (NodeIt n(_digraph); n != INVALID; ++n) {
776
+ _node_index.insert(std::make_pair(converter(map[n]), n));
777
+ }
778
+ return *this;
779
+ }
780
+
781
+ /// \brief Use previously constructed node set
782
+ ///
783
+ /// Use previously constructed node set, and specify the node
784
+ /// label map and a functor which converts the label map values to
785
+ /// \c std::string.
786
+ template <typename Map, typename Converter>
787
+ DigraphReader& useNodes(const Map& map,
788
+ const Converter& converter = Converter()) {
789
+ checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
790
+ LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
791
+ _use_nodes = true;
792
+ for (NodeIt n(_digraph); n != INVALID; ++n) {
793
+ _node_index.insert(std::make_pair(converter(map[n]), n));
794
+ }
795
+ return *this;
796
+ }
797
+
798
+ /// \brief Use previously constructed arc set
799
+ ///
800
+ /// Use previously constructed arc set, and specify the arc
801
+ /// label map.
802
+ template <typename Map>
803
+ DigraphReader& useArcs(const Map& map) {
804
+ checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
805
+ LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
806
+ _use_arcs = true;
807
+ _writer_bits::DefaultConverter<typename Map::Value> converter;
808
+ for (ArcIt a(_digraph); a != INVALID; ++a) {
809
+ _arc_index.insert(std::make_pair(converter(map[a]), a));
810
+ }
811
+ return *this;
812
+ }
813
+
814
+ /// \brief Use previously constructed arc set
815
+ ///
816
+ /// Use previously constructed arc set, and specify the arc
817
+ /// label map and a functor which converts the label map values to
818
+ /// \c std::string.
819
+ template <typename Map, typename Converter>
820
+ DigraphReader& useArcs(const Map& map,
821
+ const Converter& converter = Converter()) {
822
+ checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
823
+ LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
824
+ _use_arcs = true;
825
+ for (ArcIt a(_digraph); a != INVALID; ++a) {
826
+ _arc_index.insert(std::make_pair(converter(map[a]), a));
827
+ }
828
+ return *this;
829
+ }
830
+
831
+ /// \brief Skips the reading of node section
832
+ ///
833
+ /// Omit the reading of the node section. This implies that each node
834
+ /// map reading rule will be abandoned, and the nodes of the graph
835
+ /// will not be constructed, which usually cause that the arc set
836
+ /// could not be read due to lack of node name resolving.
837
+ /// Therefore \c skipArcs() function should also be used, or
838
+ /// \c useNodes() should be used to specify the label of the nodes.
839
+ DigraphReader& skipNodes() {
840
+ LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
841
+ _skip_nodes = true;
842
+ return *this;
843
+ }
844
+
845
+ /// \brief Skips the reading of arc section
846
+ ///
847
+ /// Omit the reading of the arc section. This implies that each arc
848
+ /// map reading rule will be abandoned, and the arcs of the graph
849
+ /// will not be constructed.
850
+ DigraphReader& skipArcs() {
851
+ LEMON_ASSERT(!_skip_arcs, "Skip arcs already set");
852
+ _skip_arcs = true;
853
+ return *this;
854
+ }
855
+
856
+ /// @}
857
+
858
+ private:
859
+
860
+ bool readLine() {
861
+ std::string str;
862
+ while(++line_num, std::getline(*_is, str)) {
863
+ line.clear(); line.str(str);
864
+ char c;
865
+ if (line >> std::ws >> c && c != '#') {
866
+ line.putback(c);
867
+ return true;
868
+ }
869
+ }
870
+ return false;
871
+ }
872
+
873
+ bool readSuccess() {
874
+ return static_cast<bool>(*_is);
875
+ }
876
+
877
+ void skipSection() {
878
+ char c;
879
+ while (readSuccess() && line >> c && c != '@') {
880
+ readLine();
881
+ }
882
+ if (readSuccess()) {
883
+ line.putback(c);
884
+ }
885
+ }
886
+
887
+ void readNodes() {
888
+
889
+ std::vector<int> map_index(_node_maps.size());
890
+ int map_num, label_index;
891
+
892
+ char c;
893
+ if (!readLine() || !(line >> c) || c == '@') {
894
+ if (readSuccess() && line) line.putback(c);
895
+ if (!_node_maps.empty())
896
+ throw FormatError("Cannot find map names");
897
+ return;
898
+ }
899
+ line.putback(c);
900
+
901
+ {
902
+ std::map<std::string, int> maps;
903
+
904
+ std::string map;
905
+ int index = 0;
906
+ while (_reader_bits::readToken(line, map)) {
907
+ if (maps.find(map) != maps.end()) {
908
+ std::ostringstream msg;
909
+ msg << "Multiple occurence of node map: " << map;
910
+ throw FormatError(msg.str());
911
+ }
912
+ maps.insert(std::make_pair(map, index));
913
+ ++index;
914
+ }
915
+
916
+ for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
917
+ std::map<std::string, int>::iterator jt =
918
+ maps.find(_node_maps[i].first);
919
+ if (jt == maps.end()) {
920
+ std::ostringstream msg;
921
+ msg << "Map not found: " << _node_maps[i].first;
922
+ throw FormatError(msg.str());
923
+ }
924
+ map_index[i] = jt->second;
925
+ }
926
+
927
+ {
928
+ std::map<std::string, int>::iterator jt = maps.find("label");
929
+ if (jt != maps.end()) {
930
+ label_index = jt->second;
931
+ } else {
932
+ label_index = -1;
933
+ }
934
+ }
935
+ map_num = maps.size();
936
+ }
937
+
938
+ while (readLine() && line >> c && c != '@') {
939
+ line.putback(c);
940
+
941
+ std::vector<std::string> tokens(map_num);
942
+ for (int i = 0; i < map_num; ++i) {
943
+ if (!_reader_bits::readToken(line, tokens[i])) {
944
+ std::ostringstream msg;
945
+ msg << "Column not found (" << i + 1 << ")";
946
+ throw FormatError(msg.str());
947
+ }
948
+ }
949
+ if (line >> std::ws >> c)
950
+ throw FormatError("Extra character at the end of line");
951
+
952
+ Node n;
953
+ if (!_use_nodes) {
954
+ n = _digraph.addNode();
955
+ if (label_index != -1)
956
+ _node_index.insert(std::make_pair(tokens[label_index], n));
957
+ } else {
958
+ if (label_index == -1)
959
+ throw FormatError("Label map not found");
960
+ typename std::map<std::string, Node>::iterator it =
961
+ _node_index.find(tokens[label_index]);
962
+ if (it == _node_index.end()) {
963
+ std::ostringstream msg;
964
+ msg << "Node with label not found: " << tokens[label_index];
965
+ throw FormatError(msg.str());
966
+ }
967
+ n = it->second;
968
+ }
969
+
970
+ for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
971
+ _node_maps[i].second->set(n, tokens[map_index[i]]);
972
+ }
973
+
974
+ }
975
+ if (readSuccess()) {
976
+ line.putback(c);
977
+ }
978
+ }
979
+
980
+ void readArcs() {
981
+
982
+ std::vector<int> map_index(_arc_maps.size());
983
+ int map_num, label_index;
984
+
985
+ char c;
986
+ if (!readLine() || !(line >> c) || c == '@') {
987
+ if (readSuccess() && line) line.putback(c);
988
+ if (!_arc_maps.empty())
989
+ throw FormatError("Cannot find map names");
990
+ return;
991
+ }
992
+ line.putback(c);
993
+
994
+ {
995
+ std::map<std::string, int> maps;
996
+
997
+ std::string map;
998
+ int index = 0;
999
+ while (_reader_bits::readToken(line, map)) {
1000
+ if(map == "-") {
1001
+ if(index!=0)
1002
+ throw FormatError("'-' is not allowed as a map name");
1003
+ else if (line >> std::ws >> c)
1004
+ throw FormatError("Extra character at the end of line");
1005
+ else break;
1006
+ }
1007
+ if (maps.find(map) != maps.end()) {
1008
+ std::ostringstream msg;
1009
+ msg << "Multiple occurence of arc map: " << map;
1010
+ throw FormatError(msg.str());
1011
+ }
1012
+ maps.insert(std::make_pair(map, index));
1013
+ ++index;
1014
+ }
1015
+
1016
+ for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1017
+ std::map<std::string, int>::iterator jt =
1018
+ maps.find(_arc_maps[i].first);
1019
+ if (jt == maps.end()) {
1020
+ std::ostringstream msg;
1021
+ msg << "Map not found: " << _arc_maps[i].first;
1022
+ throw FormatError(msg.str());
1023
+ }
1024
+ map_index[i] = jt->second;
1025
+ }
1026
+
1027
+ {
1028
+ std::map<std::string, int>::iterator jt = maps.find("label");
1029
+ if (jt != maps.end()) {
1030
+ label_index = jt->second;
1031
+ } else {
1032
+ label_index = -1;
1033
+ }
1034
+ }
1035
+ map_num = maps.size();
1036
+ }
1037
+
1038
+ while (readLine() && line >> c && c != '@') {
1039
+ line.putback(c);
1040
+
1041
+ std::string source_token;
1042
+ std::string target_token;
1043
+
1044
+ if (!_reader_bits::readToken(line, source_token))
1045
+ throw FormatError("Source not found");
1046
+
1047
+ if (!_reader_bits::readToken(line, target_token))
1048
+ throw FormatError("Target not found");
1049
+
1050
+ std::vector<std::string> tokens(map_num);
1051
+ for (int i = 0; i < map_num; ++i) {
1052
+ if (!_reader_bits::readToken(line, tokens[i])) {
1053
+ std::ostringstream msg;
1054
+ msg << "Column not found (" << i + 1 << ")";
1055
+ throw FormatError(msg.str());
1056
+ }
1057
+ }
1058
+ if (line >> std::ws >> c)
1059
+ throw FormatError("Extra character at the end of line");
1060
+
1061
+ Arc a;
1062
+ if (!_use_arcs) {
1063
+
1064
+ typename NodeIndex::iterator it;
1065
+
1066
+ it = _node_index.find(source_token);
1067
+ if (it == _node_index.end()) {
1068
+ std::ostringstream msg;
1069
+ msg << "Item not found: " << source_token;
1070
+ throw FormatError(msg.str());
1071
+ }
1072
+ Node source = it->second;
1073
+
1074
+ it = _node_index.find(target_token);
1075
+ if (it == _node_index.end()) {
1076
+ std::ostringstream msg;
1077
+ msg << "Item not found: " << target_token;
1078
+ throw FormatError(msg.str());
1079
+ }
1080
+ Node target = it->second;
1081
+
1082
+ a = _digraph.addArc(source, target);
1083
+ if (label_index != -1)
1084
+ _arc_index.insert(std::make_pair(tokens[label_index], a));
1085
+ } else {
1086
+ if (label_index == -1)
1087
+ throw FormatError("Label map not found");
1088
+ typename std::map<std::string, Arc>::iterator it =
1089
+ _arc_index.find(tokens[label_index]);
1090
+ if (it == _arc_index.end()) {
1091
+ std::ostringstream msg;
1092
+ msg << "Arc with label not found: " << tokens[label_index];
1093
+ throw FormatError(msg.str());
1094
+ }
1095
+ a = it->second;
1096
+ }
1097
+
1098
+ for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1099
+ _arc_maps[i].second->set(a, tokens[map_index[i]]);
1100
+ }
1101
+
1102
+ }
1103
+ if (readSuccess()) {
1104
+ line.putback(c);
1105
+ }
1106
+ }
1107
+
1108
+ void readAttributes() {
1109
+
1110
+ std::set<std::string> read_attr;
1111
+
1112
+ char c;
1113
+ while (readLine() && line >> c && c != '@') {
1114
+ line.putback(c);
1115
+
1116
+ std::string attr, token;
1117
+ if (!_reader_bits::readToken(line, attr))
1118
+ throw FormatError("Attribute name not found");
1119
+ if (!_reader_bits::readToken(line, token))
1120
+ throw FormatError("Attribute value not found");
1121
+ if (line >> c)
1122
+ throw FormatError("Extra character at the end of line");
1123
+
1124
+ {
1125
+ std::set<std::string>::iterator it = read_attr.find(attr);
1126
+ if (it != read_attr.end()) {
1127
+ std::ostringstream msg;
1128
+ msg << "Multiple occurence of attribute: " << attr;
1129
+ throw FormatError(msg.str());
1130
+ }
1131
+ read_attr.insert(attr);
1132
+ }
1133
+
1134
+ {
1135
+ typename Attributes::iterator it = _attributes.lower_bound(attr);
1136
+ while (it != _attributes.end() && it->first == attr) {
1137
+ it->second->set(token);
1138
+ ++it;
1139
+ }
1140
+ }
1141
+
1142
+ }
1143
+ if (readSuccess()) {
1144
+ line.putback(c);
1145
+ }
1146
+ for (typename Attributes::iterator it = _attributes.begin();
1147
+ it != _attributes.end(); ++it) {
1148
+ if (read_attr.find(it->first) == read_attr.end()) {
1149
+ std::ostringstream msg;
1150
+ msg << "Attribute not found: " << it->first;
1151
+ throw FormatError(msg.str());
1152
+ }
1153
+ }
1154
+ }
1155
+
1156
+ public:
1157
+
1158
+ /// \name Execution of the Reader
1159
+ /// @{
1160
+
1161
+ /// \brief Start the batch processing
1162
+ ///
1163
+ /// This function starts the batch processing
1164
+ void run() {
1165
+ LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1166
+
1167
+ bool nodes_done = _skip_nodes;
1168
+ bool arcs_done = _skip_arcs;
1169
+ bool attributes_done = false;
1170
+
1171
+ line_num = 0;
1172
+ readLine();
1173
+ skipSection();
1174
+
1175
+ while (readSuccess()) {
1176
+ try {
1177
+ char c;
1178
+ std::string section, caption;
1179
+ line >> c;
1180
+ _reader_bits::readToken(line, section);
1181
+ _reader_bits::readToken(line, caption);
1182
+
1183
+ if (line >> c)
1184
+ throw FormatError("Extra character at the end of line");
1185
+
1186
+ if (section == "nodes" && !nodes_done) {
1187
+ if (_nodes_caption.empty() || _nodes_caption == caption) {
1188
+ readNodes();
1189
+ nodes_done = true;
1190
+ }
1191
+ } else if ((section == "arcs" || section == "edges") &&
1192
+ !arcs_done) {
1193
+ if (_arcs_caption.empty() || _arcs_caption == caption) {
1194
+ readArcs();
1195
+ arcs_done = true;
1196
+ }
1197
+ } else if (section == "attributes" && !attributes_done) {
1198
+ if (_attributes_caption.empty() || _attributes_caption == caption) {
1199
+ readAttributes();
1200
+ attributes_done = true;
1201
+ }
1202
+ } else {
1203
+ readLine();
1204
+ skipSection();
1205
+ }
1206
+ } catch (FormatError& error) {
1207
+ error.line(line_num);
1208
+ error.file(_filename);
1209
+ throw;
1210
+ }
1211
+ }
1212
+
1213
+ if (!nodes_done) {
1214
+ throw FormatError("Section @nodes not found");
1215
+ }
1216
+
1217
+ if (!arcs_done) {
1218
+ throw FormatError("Section @arcs not found");
1219
+ }
1220
+
1221
+ if (!attributes_done && !_attributes.empty()) {
1222
+ throw FormatError("Section @attributes not found");
1223
+ }
1224
+
1225
+ }
1226
+
1227
+ /// @}
1228
+
1229
+ };
1230
+
1231
+ /// \ingroup lemon_io
1232
+ ///
1233
+ /// \brief Return a \ref lemon::DigraphReader "DigraphReader" class
1234
+ ///
1235
+ /// This function just returns a \ref lemon::DigraphReader
1236
+ /// "DigraphReader" class.
1237
+ ///
1238
+ /// With this function a digraph can be read from an
1239
+ /// \ref lgf-format "LGF" file or input stream with several maps and
1240
+ /// attributes. For example, there is network flow problem on a
1241
+ /// digraph, i.e. a digraph with a \e capacity map on the arcs and
1242
+ /// \e source and \e target nodes. This digraph can be read with the
1243
+ /// following code:
1244
+ ///
1245
+ ///\code
1246
+ ///ListDigraph digraph;
1247
+ ///ListDigraph::ArcMap<int> cm(digraph);
1248
+ ///ListDigraph::Node src, trg;
1249
+ ///digraphReader(digraph, std::cin).
1250
+ /// arcMap("capacity", cap).
1251
+ /// node("source", src).
1252
+ /// node("target", trg).
1253
+ /// run();
1254
+ ///\endcode
1255
+ ///
1256
+ /// For a complete documentation, please see the
1257
+ /// \ref lemon::DigraphReader "DigraphReader"
1258
+ /// class documentation.
1259
+ /// \warning Don't forget to put the \ref lemon::DigraphReader::run() "run()"
1260
+ /// to the end of the parameter list.
1261
+ /// \relates DigraphReader
1262
+ /// \sa digraphReader(TDGR& digraph, const std::string& fn)
1263
+ /// \sa digraphReader(TDGR& digraph, const char* fn)
1264
+ template <typename TDGR>
1265
+ DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is) {
1266
+ DigraphReader<TDGR> tmp(digraph, is);
1267
+ return tmp;
1268
+ }
1269
+
1270
+ /// \brief Return a \ref DigraphReader class
1271
+ ///
1272
+ /// This function just returns a \ref DigraphReader class.
1273
+ /// \relates DigraphReader
1274
+ /// \sa digraphReader(TDGR& digraph, std::istream& is)
1275
+ template <typename TDGR>
1276
+ DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn) {
1277
+ DigraphReader<TDGR> tmp(digraph, fn);
1278
+ return tmp;
1279
+ }
1280
+
1281
+ /// \brief Return a \ref DigraphReader class
1282
+ ///
1283
+ /// This function just returns a \ref DigraphReader class.
1284
+ /// \relates DigraphReader
1285
+ /// \sa digraphReader(TDGR& digraph, std::istream& is)
1286
+ template <typename TDGR>
1287
+ DigraphReader<TDGR> digraphReader(TDGR& digraph, const char* fn) {
1288
+ DigraphReader<TDGR> tmp(digraph, fn);
1289
+ return tmp;
1290
+ }
1291
+
1292
+ template <typename GR>
1293
+ class GraphReader;
1294
+
1295
+ template <typename TGR>
1296
+ GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin);
1297
+ template <typename TGR>
1298
+ GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
1299
+ template <typename TGR>
1300
+ GraphReader<TGR> graphReader(TGR& graph, const char *fn);
1301
+
1302
+ /// \ingroup lemon_io
1303
+ ///
1304
+ /// \brief \ref lgf-format "LGF" reader for undirected graphs
1305
+ ///
1306
+ /// This utility reads an \ref lgf-format "LGF" file.
1307
+ ///
1308
+ /// It can be used almost the same way as \c DigraphReader.
1309
+ /// The only difference is that this class can handle edges and
1310
+ /// edge maps as well as arcs and arc maps.
1311
+ ///
1312
+ /// The columns in the \c \@edges (or \c \@arcs) section are the
1313
+ /// edge maps. However, if there are two maps with the same name
1314
+ /// prefixed with \c '+' and \c '-', then these can be read into an
1315
+ /// arc map. Similarly, an attribute can be read into an arc, if
1316
+ /// it's value is an edge label prefixed with \c '+' or \c '-'.
1317
+ template <typename GR>
1318
+ class GraphReader {
1319
+ public:
1320
+
1321
+ typedef GR Graph;
1322
+
1323
+ private:
1324
+
1325
+ TEMPLATE_GRAPH_TYPEDEFS(GR);
1326
+
1327
+ std::istream* _is;
1328
+ bool local_is;
1329
+ std::string _filename;
1330
+
1331
+ GR& _graph;
1332
+
1333
+ std::string _nodes_caption;
1334
+ std::string _edges_caption;
1335
+ std::string _attributes_caption;
1336
+
1337
+ typedef std::map<std::string, Node> NodeIndex;
1338
+ NodeIndex _node_index;
1339
+ typedef std::map<std::string, Edge> EdgeIndex;
1340
+ EdgeIndex _edge_index;
1341
+
1342
+ typedef std::vector<std::pair<std::string,
1343
+ _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1344
+ NodeMaps _node_maps;
1345
+
1346
+ typedef std::vector<std::pair<std::string,
1347
+ _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1348
+ EdgeMaps _edge_maps;
1349
+
1350
+ typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1351
+ Attributes;
1352
+ Attributes _attributes;
1353
+
1354
+ bool _use_nodes;
1355
+ bool _use_edges;
1356
+
1357
+ bool _skip_nodes;
1358
+ bool _skip_edges;
1359
+
1360
+ int line_num;
1361
+ std::istringstream line;
1362
+
1363
+ public:
1364
+
1365
+ /// \brief Constructor
1366
+ ///
1367
+ /// Construct an undirected graph reader, which reads from the given
1368
+ /// input stream.
1369
+ GraphReader(GR& graph, std::istream& is = std::cin)
1370
+ : _is(&is), local_is(false), _graph(graph),
1371
+ _use_nodes(false), _use_edges(false),
1372
+ _skip_nodes(false), _skip_edges(false) {}
1373
+
1374
+ /// \brief Constructor
1375
+ ///
1376
+ /// Construct an undirected graph reader, which reads from the given
1377
+ /// file.
1378
+ GraphReader(GR& graph, const std::string& fn)
1379
+ : _is(new std::ifstream(fn.c_str())), local_is(true),
1380
+ _filename(fn), _graph(graph),
1381
+ _use_nodes(false), _use_edges(false),
1382
+ _skip_nodes(false), _skip_edges(false) {
1383
+ if (!(*_is)) {
1384
+ delete _is;
1385
+ throw IoError("Cannot open file", fn);
1386
+ }
1387
+ }
1388
+
1389
+ /// \brief Constructor
1390
+ ///
1391
+ /// Construct an undirected graph reader, which reads from the given
1392
+ /// file.
1393
+ GraphReader(GR& graph, const char* fn)
1394
+ : _is(new std::ifstream(fn)), local_is(true),
1395
+ _filename(fn), _graph(graph),
1396
+ _use_nodes(false), _use_edges(false),
1397
+ _skip_nodes(false), _skip_edges(false) {
1398
+ if (!(*_is)) {
1399
+ delete _is;
1400
+ throw IoError("Cannot open file", fn);
1401
+ }
1402
+ }
1403
+
1404
+ /// \brief Destructor
1405
+ ~GraphReader() {
1406
+ for (typename NodeMaps::iterator it = _node_maps.begin();
1407
+ it != _node_maps.end(); ++it) {
1408
+ delete it->second;
1409
+ }
1410
+
1411
+ for (typename EdgeMaps::iterator it = _edge_maps.begin();
1412
+ it != _edge_maps.end(); ++it) {
1413
+ delete it->second;
1414
+ }
1415
+
1416
+ for (typename Attributes::iterator it = _attributes.begin();
1417
+ it != _attributes.end(); ++it) {
1418
+ delete it->second;
1419
+ }
1420
+
1421
+ if (local_is) {
1422
+ delete _is;
1423
+ }
1424
+
1425
+ }
1426
+
1427
+ private:
1428
+ template <typename TGR>
1429
+ friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is);
1430
+ template <typename TGR>
1431
+ friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
1432
+ template <typename TGR>
1433
+ friend GraphReader<TGR> graphReader(TGR& graph, const char *fn);
1434
+
1435
+ GraphReader(GraphReader& other)
1436
+ : _is(other._is), local_is(other.local_is), _graph(other._graph),
1437
+ _use_nodes(other._use_nodes), _use_edges(other._use_edges),
1438
+ _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1439
+
1440
+ other._is = 0;
1441
+ other.local_is = false;
1442
+
1443
+ _node_index.swap(other._node_index);
1444
+ _edge_index.swap(other._edge_index);
1445
+
1446
+ _node_maps.swap(other._node_maps);
1447
+ _edge_maps.swap(other._edge_maps);
1448
+ _attributes.swap(other._attributes);
1449
+
1450
+ _nodes_caption = other._nodes_caption;
1451
+ _edges_caption = other._edges_caption;
1452
+ _attributes_caption = other._attributes_caption;
1453
+
1454
+ }
1455
+
1456
+ GraphReader& operator=(const GraphReader&);
1457
+
1458
+ public:
1459
+
1460
+ /// \name Reading Rules
1461
+ /// @{
1462
+
1463
+ /// \brief Node map reading rule
1464
+ ///
1465
+ /// Add a node map reading rule to the reader.
1466
+ template <typename Map>
1467
+ GraphReader& nodeMap(const std::string& caption, Map& map) {
1468
+ checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1469
+ _reader_bits::MapStorageBase<Node>* storage =
1470
+ new _reader_bits::MapStorage<Node, Map>(map);
1471
+ _node_maps.push_back(std::make_pair(caption, storage));
1472
+ return *this;
1473
+ }
1474
+
1475
+ /// \brief Node map reading rule
1476
+ ///
1477
+ /// Add a node map reading rule with specialized converter to the
1478
+ /// reader.
1479
+ template <typename Map, typename Converter>
1480
+ GraphReader& nodeMap(const std::string& caption, Map& map,
1481
+ const Converter& converter = Converter()) {
1482
+ checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1483
+ _reader_bits::MapStorageBase<Node>* storage =
1484
+ new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1485
+ _node_maps.push_back(std::make_pair(caption, storage));
1486
+ return *this;
1487
+ }
1488
+
1489
+ /// \brief Edge map reading rule
1490
+ ///
1491
+ /// Add an edge map reading rule to the reader.
1492
+ template <typename Map>
1493
+ GraphReader& edgeMap(const std::string& caption, Map& map) {
1494
+ checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1495
+ _reader_bits::MapStorageBase<Edge>* storage =
1496
+ new _reader_bits::MapStorage<Edge, Map>(map);
1497
+ _edge_maps.push_back(std::make_pair(caption, storage));
1498
+ return *this;
1499
+ }
1500
+
1501
+ /// \brief Edge map reading rule
1502
+ ///
1503
+ /// Add an edge map reading rule with specialized converter to the
1504
+ /// reader.
1505
+ template <typename Map, typename Converter>
1506
+ GraphReader& edgeMap(const std::string& caption, Map& map,
1507
+ const Converter& converter = Converter()) {
1508
+ checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1509
+ _reader_bits::MapStorageBase<Edge>* storage =
1510
+ new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1511
+ _edge_maps.push_back(std::make_pair(caption, storage));
1512
+ return *this;
1513
+ }
1514
+
1515
+ /// \brief Arc map reading rule
1516
+ ///
1517
+ /// Add an arc map reading rule to the reader.
1518
+ template <typename Map>
1519
+ GraphReader& arcMap(const std::string& caption, Map& map) {
1520
+ checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1521
+ _reader_bits::MapStorageBase<Edge>* forward_storage =
1522
+ new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1523
+ _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1524
+ _reader_bits::MapStorageBase<Edge>* backward_storage =
1525
+ new _reader_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
1526
+ _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1527
+ return *this;
1528
+ }
1529
+
1530
+ /// \brief Arc map reading rule
1531
+ ///
1532
+ /// Add an arc map reading rule with specialized converter to the
1533
+ /// reader.
1534
+ template <typename Map, typename Converter>
1535
+ GraphReader& arcMap(const std::string& caption, Map& map,
1536
+ const Converter& converter = Converter()) {
1537
+ checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1538
+ _reader_bits::MapStorageBase<Edge>* forward_storage =
1539
+ new _reader_bits::GraphArcMapStorage<GR, true, Map, Converter>
1540
+ (_graph, map, converter);
1541
+ _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1542
+ _reader_bits::MapStorageBase<Edge>* backward_storage =
1543
+ new _reader_bits::GraphArcMapStorage<GR, false, Map, Converter>
1544
+ (_graph, map, converter);
1545
+ _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1546
+ return *this;
1547
+ }
1548
+
1549
+ /// \brief Attribute reading rule
1550
+ ///
1551
+ /// Add an attribute reading rule to the reader.
1552
+ template <typename Value>
1553
+ GraphReader& attribute(const std::string& caption, Value& value) {
1554
+ _reader_bits::ValueStorageBase* storage =
1555
+ new _reader_bits::ValueStorage<Value>(value);
1556
+ _attributes.insert(std::make_pair(caption, storage));
1557
+ return *this;
1558
+ }
1559
+
1560
+ /// \brief Attribute reading rule
1561
+ ///
1562
+ /// Add an attribute reading rule with specialized converter to the
1563
+ /// reader.
1564
+ template <typename Value, typename Converter>
1565
+ GraphReader& attribute(const std::string& caption, Value& value,
1566
+ const Converter& converter = Converter()) {
1567
+ _reader_bits::ValueStorageBase* storage =
1568
+ new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1569
+ _attributes.insert(std::make_pair(caption, storage));
1570
+ return *this;
1571
+ }
1572
+
1573
+ /// \brief Node reading rule
1574
+ ///
1575
+ /// Add a node reading rule to reader.
1576
+ GraphReader& node(const std::string& caption, Node& node) {
1577
+ typedef _reader_bits::MapLookUpConverter<Node> Converter;
1578
+ Converter converter(_node_index);
1579
+ _reader_bits::ValueStorageBase* storage =
1580
+ new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1581
+ _attributes.insert(std::make_pair(caption, storage));
1582
+ return *this;
1583
+ }
1584
+
1585
+ /// \brief Edge reading rule
1586
+ ///
1587
+ /// Add an edge reading rule to reader.
1588
+ GraphReader& edge(const std::string& caption, Edge& edge) {
1589
+ typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1590
+ Converter converter(_edge_index);
1591
+ _reader_bits::ValueStorageBase* storage =
1592
+ new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1593
+ _attributes.insert(std::make_pair(caption, storage));
1594
+ return *this;
1595
+ }
1596
+
1597
+ /// \brief Arc reading rule
1598
+ ///
1599
+ /// Add an arc reading rule to reader.
1600
+ GraphReader& arc(const std::string& caption, Arc& arc) {
1601
+ typedef _reader_bits::GraphArcLookUpConverter<GR> Converter;
1602
+ Converter converter(_graph, _edge_index);
1603
+ _reader_bits::ValueStorageBase* storage =
1604
+ new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1605
+ _attributes.insert(std::make_pair(caption, storage));
1606
+ return *this;
1607
+ }
1608
+
1609
+ /// @}
1610
+
1611
+ /// \name Select Section by Name
1612
+ /// @{
1613
+
1614
+ /// \brief Set \c \@nodes section to be read
1615
+ ///
1616
+ /// Set \c \@nodes section to be read.
1617
+ GraphReader& nodes(const std::string& caption) {
1618
+ _nodes_caption = caption;
1619
+ return *this;
1620
+ }
1621
+
1622
+ /// \brief Set \c \@edges section to be read
1623
+ ///
1624
+ /// Set \c \@edges section to be read.
1625
+ GraphReader& edges(const std::string& caption) {
1626
+ _edges_caption = caption;
1627
+ return *this;
1628
+ }
1629
+
1630
+ /// \brief Set \c \@attributes section to be read
1631
+ ///
1632
+ /// Set \c \@attributes section to be read.
1633
+ GraphReader& attributes(const std::string& caption) {
1634
+ _attributes_caption = caption;
1635
+ return *this;
1636
+ }
1637
+
1638
+ /// @}
1639
+
1640
+ /// \name Using Previously Constructed Node or Edge Set
1641
+ /// @{
1642
+
1643
+ /// \brief Use previously constructed node set
1644
+ ///
1645
+ /// Use previously constructed node set, and specify the node
1646
+ /// label map.
1647
+ template <typename Map>
1648
+ GraphReader& useNodes(const Map& map) {
1649
+ checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1650
+ LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1651
+ _use_nodes = true;
1652
+ _writer_bits::DefaultConverter<typename Map::Value> converter;
1653
+ for (NodeIt n(_graph); n != INVALID; ++n) {
1654
+ _node_index.insert(std::make_pair(converter(map[n]), n));
1655
+ }
1656
+ return *this;
1657
+ }
1658
+
1659
+ /// \brief Use previously constructed node set
1660
+ ///
1661
+ /// Use previously constructed node set, and specify the node
1662
+ /// label map and a functor which converts the label map values to
1663
+ /// \c std::string.
1664
+ template <typename Map, typename Converter>
1665
+ GraphReader& useNodes(const Map& map,
1666
+ const Converter& converter = Converter()) {
1667
+ checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1668
+ LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1669
+ _use_nodes = true;
1670
+ for (NodeIt n(_graph); n != INVALID; ++n) {
1671
+ _node_index.insert(std::make_pair(converter(map[n]), n));
1672
+ }
1673
+ return *this;
1674
+ }
1675
+
1676
+ /// \brief Use previously constructed edge set
1677
+ ///
1678
+ /// Use previously constructed edge set, and specify the edge
1679
+ /// label map.
1680
+ template <typename Map>
1681
+ GraphReader& useEdges(const Map& map) {
1682
+ checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1683
+ LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1684
+ _use_edges = true;
1685
+ _writer_bits::DefaultConverter<typename Map::Value> converter;
1686
+ for (EdgeIt a(_graph); a != INVALID; ++a) {
1687
+ _edge_index.insert(std::make_pair(converter(map[a]), a));
1688
+ }
1689
+ return *this;
1690
+ }
1691
+
1692
+ /// \brief Use previously constructed edge set
1693
+ ///
1694
+ /// Use previously constructed edge set, and specify the edge
1695
+ /// label map and a functor which converts the label map values to
1696
+ /// \c std::string.
1697
+ template <typename Map, typename Converter>
1698
+ GraphReader& useEdges(const Map& map,
1699
+ const Converter& converter = Converter()) {
1700
+ checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1701
+ LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1702
+ _use_edges = true;
1703
+ for (EdgeIt a(_graph); a != INVALID; ++a) {
1704
+ _edge_index.insert(std::make_pair(converter(map[a]), a));
1705
+ }
1706
+ return *this;
1707
+ }
1708
+
1709
+ /// \brief Skip the reading of node section
1710
+ ///
1711
+ /// Omit the reading of the node section. This implies that each node
1712
+ /// map reading rule will be abandoned, and the nodes of the graph
1713
+ /// will not be constructed, which usually cause that the edge set
1714
+ /// could not be read due to lack of node name
1715
+ /// could not be read due to lack of node name resolving.
1716
+ /// Therefore \c skipEdges() function should also be used, or
1717
+ /// \c useNodes() should be used to specify the label of the nodes.
1718
+ GraphReader& skipNodes() {
1719
+ LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
1720
+ _skip_nodes = true;
1721
+ return *this;
1722
+ }
1723
+
1724
+ /// \brief Skip the reading of edge section
1725
+ ///
1726
+ /// Omit the reading of the edge section. This implies that each edge
1727
+ /// map reading rule will be abandoned, and the edges of the graph
1728
+ /// will not be constructed.
1729
+ GraphReader& skipEdges() {
1730
+ LEMON_ASSERT(!_skip_edges, "Skip edges already set");
1731
+ _skip_edges = true;
1732
+ return *this;
1733
+ }
1734
+
1735
+ /// @}
1736
+
1737
+ private:
1738
+
1739
+ bool readLine() {
1740
+ std::string str;
1741
+ while(++line_num, std::getline(*_is, str)) {
1742
+ line.clear(); line.str(str);
1743
+ char c;
1744
+ if (line >> std::ws >> c && c != '#') {
1745
+ line.putback(c);
1746
+ return true;
1747
+ }
1748
+ }
1749
+ return false;
1750
+ }
1751
+
1752
+ bool readSuccess() {
1753
+ return static_cast<bool>(*_is);
1754
+ }
1755
+
1756
+ void skipSection() {
1757
+ char c;
1758
+ while (readSuccess() && line >> c && c != '@') {
1759
+ readLine();
1760
+ }
1761
+ if (readSuccess()) {
1762
+ line.putback(c);
1763
+ }
1764
+ }
1765
+
1766
+ void readNodes() {
1767
+
1768
+ std::vector<int> map_index(_node_maps.size());
1769
+ int map_num, label_index;
1770
+
1771
+ char c;
1772
+ if (!readLine() || !(line >> c) || c == '@') {
1773
+ if (readSuccess() && line) line.putback(c);
1774
+ if (!_node_maps.empty())
1775
+ throw FormatError("Cannot find map names");
1776
+ return;
1777
+ }
1778
+ line.putback(c);
1779
+
1780
+ {
1781
+ std::map<std::string, int> maps;
1782
+
1783
+ std::string map;
1784
+ int index = 0;
1785
+ while (_reader_bits::readToken(line, map)) {
1786
+ if (maps.find(map) != maps.end()) {
1787
+ std::ostringstream msg;
1788
+ msg << "Multiple occurence of node map: " << map;
1789
+ throw FormatError(msg.str());
1790
+ }
1791
+ maps.insert(std::make_pair(map, index));
1792
+ ++index;
1793
+ }
1794
+
1795
+ for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1796
+ std::map<std::string, int>::iterator jt =
1797
+ maps.find(_node_maps[i].first);
1798
+ if (jt == maps.end()) {
1799
+ std::ostringstream msg;
1800
+ msg << "Map not found: " << _node_maps[i].first;
1801
+ throw FormatError(msg.str());
1802
+ }
1803
+ map_index[i] = jt->second;
1804
+ }
1805
+
1806
+ {
1807
+ std::map<std::string, int>::iterator jt = maps.find("label");
1808
+ if (jt != maps.end()) {
1809
+ label_index = jt->second;
1810
+ } else {
1811
+ label_index = -1;
1812
+ }
1813
+ }
1814
+ map_num = maps.size();
1815
+ }
1816
+
1817
+ while (readLine() && line >> c && c != '@') {
1818
+ line.putback(c);
1819
+
1820
+ std::vector<std::string> tokens(map_num);
1821
+ for (int i = 0; i < map_num; ++i) {
1822
+ if (!_reader_bits::readToken(line, tokens[i])) {
1823
+ std::ostringstream msg;
1824
+ msg << "Column not found (" << i + 1 << ")";
1825
+ throw FormatError(msg.str());
1826
+ }
1827
+ }
1828
+ if (line >> std::ws >> c)
1829
+ throw FormatError("Extra character at the end of line");
1830
+
1831
+ Node n;
1832
+ if (!_use_nodes) {
1833
+ n = _graph.addNode();
1834
+ if (label_index != -1)
1835
+ _node_index.insert(std::make_pair(tokens[label_index], n));
1836
+ } else {
1837
+ if (label_index == -1)
1838
+ throw FormatError("Label map not found");
1839
+ typename std::map<std::string, Node>::iterator it =
1840
+ _node_index.find(tokens[label_index]);
1841
+ if (it == _node_index.end()) {
1842
+ std::ostringstream msg;
1843
+ msg << "Node with label not found: " << tokens[label_index];
1844
+ throw FormatError(msg.str());
1845
+ }
1846
+ n = it->second;
1847
+ }
1848
+
1849
+ for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1850
+ _node_maps[i].second->set(n, tokens[map_index[i]]);
1851
+ }
1852
+
1853
+ }
1854
+ if (readSuccess()) {
1855
+ line.putback(c);
1856
+ }
1857
+ }
1858
+
1859
+ void readEdges() {
1860
+
1861
+ std::vector<int> map_index(_edge_maps.size());
1862
+ int map_num, label_index;
1863
+
1864
+ char c;
1865
+ if (!readLine() || !(line >> c) || c == '@') {
1866
+ if (readSuccess() && line) line.putback(c);
1867
+ if (!_edge_maps.empty())
1868
+ throw FormatError("Cannot find map names");
1869
+ return;
1870
+ }
1871
+ line.putback(c);
1872
+
1873
+ {
1874
+ std::map<std::string, int> maps;
1875
+
1876
+ std::string map;
1877
+ int index = 0;
1878
+ while (_reader_bits::readToken(line, map)) {
1879
+ if(map == "-") {
1880
+ if(index!=0)
1881
+ throw FormatError("'-' is not allowed as a map name");
1882
+ else if (line >> std::ws >> c)
1883
+ throw FormatError("Extra character at the end of line");
1884
+ else break;
1885
+ }
1886
+ if (maps.find(map) != maps.end()) {
1887
+ std::ostringstream msg;
1888
+ msg << "Multiple occurence of edge map: " << map;
1889
+ throw FormatError(msg.str());
1890
+ }
1891
+ maps.insert(std::make_pair(map, index));
1892
+ ++index;
1893
+ }
1894
+
1895
+ for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1896
+ std::map<std::string, int>::iterator jt =
1897
+ maps.find(_edge_maps[i].first);
1898
+ if (jt == maps.end()) {
1899
+ std::ostringstream msg;
1900
+ msg << "Map not found: " << _edge_maps[i].first;
1901
+ throw FormatError(msg.str());
1902
+ }
1903
+ map_index[i] = jt->second;
1904
+ }
1905
+
1906
+ {
1907
+ std::map<std::string, int>::iterator jt = maps.find("label");
1908
+ if (jt != maps.end()) {
1909
+ label_index = jt->second;
1910
+ } else {
1911
+ label_index = -1;
1912
+ }
1913
+ }
1914
+ map_num = maps.size();
1915
+ }
1916
+
1917
+ while (readLine() && line >> c && c != '@') {
1918
+ line.putback(c);
1919
+
1920
+ std::string source_token;
1921
+ std::string target_token;
1922
+
1923
+ if (!_reader_bits::readToken(line, source_token))
1924
+ throw FormatError("Node u not found");
1925
+
1926
+ if (!_reader_bits::readToken(line, target_token))
1927
+ throw FormatError("Node v not found");
1928
+
1929
+ std::vector<std::string> tokens(map_num);
1930
+ for (int i = 0; i < map_num; ++i) {
1931
+ if (!_reader_bits::readToken(line, tokens[i])) {
1932
+ std::ostringstream msg;
1933
+ msg << "Column not found (" << i + 1 << ")";
1934
+ throw FormatError(msg.str());
1935
+ }
1936
+ }
1937
+ if (line >> std::ws >> c)
1938
+ throw FormatError("Extra character at the end of line");
1939
+
1940
+ Edge e;
1941
+ if (!_use_edges) {
1942
+
1943
+ typename NodeIndex::iterator it;
1944
+
1945
+ it = _node_index.find(source_token);
1946
+ if (it == _node_index.end()) {
1947
+ std::ostringstream msg;
1948
+ msg << "Item not found: " << source_token;
1949
+ throw FormatError(msg.str());
1950
+ }
1951
+ Node source = it->second;
1952
+
1953
+ it = _node_index.find(target_token);
1954
+ if (it == _node_index.end()) {
1955
+ std::ostringstream msg;
1956
+ msg << "Item not found: " << target_token;
1957
+ throw FormatError(msg.str());
1958
+ }
1959
+ Node target = it->second;
1960
+
1961
+ e = _graph.addEdge(source, target);
1962
+ if (label_index != -1)
1963
+ _edge_index.insert(std::make_pair(tokens[label_index], e));
1964
+ } else {
1965
+ if (label_index == -1)
1966
+ throw FormatError("Label map not found");
1967
+ typename std::map<std::string, Edge>::iterator it =
1968
+ _edge_index.find(tokens[label_index]);
1969
+ if (it == _edge_index.end()) {
1970
+ std::ostringstream msg;
1971
+ msg << "Edge with label not found: " << tokens[label_index];
1972
+ throw FormatError(msg.str());
1973
+ }
1974
+ e = it->second;
1975
+ }
1976
+
1977
+ for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1978
+ _edge_maps[i].second->set(e, tokens[map_index[i]]);
1979
+ }
1980
+
1981
+ }
1982
+ if (readSuccess()) {
1983
+ line.putback(c);
1984
+ }
1985
+ }
1986
+
1987
+ void readAttributes() {
1988
+
1989
+ std::set<std::string> read_attr;
1990
+
1991
+ char c;
1992
+ while (readLine() && line >> c && c != '@') {
1993
+ line.putback(c);
1994
+
1995
+ std::string attr, token;
1996
+ if (!_reader_bits::readToken(line, attr))
1997
+ throw FormatError("Attribute name not found");
1998
+ if (!_reader_bits::readToken(line, token))
1999
+ throw FormatError("Attribute value not found");
2000
+ if (line >> c)
2001
+ throw FormatError("Extra character at the end of line");
2002
+
2003
+ {
2004
+ std::set<std::string>::iterator it = read_attr.find(attr);
2005
+ if (it != read_attr.end()) {
2006
+ std::ostringstream msg;
2007
+ msg << "Multiple occurence of attribute: " << attr;
2008
+ throw FormatError(msg.str());
2009
+ }
2010
+ read_attr.insert(attr);
2011
+ }
2012
+
2013
+ {
2014
+ typename Attributes::iterator it = _attributes.lower_bound(attr);
2015
+ while (it != _attributes.end() && it->first == attr) {
2016
+ it->second->set(token);
2017
+ ++it;
2018
+ }
2019
+ }
2020
+
2021
+ }
2022
+ if (readSuccess()) {
2023
+ line.putback(c);
2024
+ }
2025
+ for (typename Attributes::iterator it = _attributes.begin();
2026
+ it != _attributes.end(); ++it) {
2027
+ if (read_attr.find(it->first) == read_attr.end()) {
2028
+ std::ostringstream msg;
2029
+ msg << "Attribute not found: " << it->first;
2030
+ throw FormatError(msg.str());
2031
+ }
2032
+ }
2033
+ }
2034
+
2035
+ public:
2036
+
2037
+ /// \name Execution of the Reader
2038
+ /// @{
2039
+
2040
+ /// \brief Start the batch processing
2041
+ ///
2042
+ /// This function starts the batch processing
2043
+ void run() {
2044
+
2045
+ LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2046
+
2047
+ bool nodes_done = _skip_nodes;
2048
+ bool edges_done = _skip_edges;
2049
+ bool attributes_done = false;
2050
+
2051
+ line_num = 0;
2052
+ readLine();
2053
+ skipSection();
2054
+
2055
+ while (readSuccess()) {
2056
+ try {
2057
+ char c;
2058
+ std::string section, caption;
2059
+ line >> c;
2060
+ _reader_bits::readToken(line, section);
2061
+ _reader_bits::readToken(line, caption);
2062
+
2063
+ if (line >> c)
2064
+ throw FormatError("Extra character at the end of line");
2065
+
2066
+ if (section == "nodes" && !nodes_done) {
2067
+ if (_nodes_caption.empty() || _nodes_caption == caption) {
2068
+ readNodes();
2069
+ nodes_done = true;
2070
+ }
2071
+ } else if ((section == "edges" || section == "arcs") &&
2072
+ !edges_done) {
2073
+ if (_edges_caption.empty() || _edges_caption == caption) {
2074
+ readEdges();
2075
+ edges_done = true;
2076
+ }
2077
+ } else if (section == "attributes" && !attributes_done) {
2078
+ if (_attributes_caption.empty() || _attributes_caption == caption) {
2079
+ readAttributes();
2080
+ attributes_done = true;
2081
+ }
2082
+ } else {
2083
+ readLine();
2084
+ skipSection();
2085
+ }
2086
+ } catch (FormatError& error) {
2087
+ error.line(line_num);
2088
+ error.file(_filename);
2089
+ throw;
2090
+ }
2091
+ }
2092
+
2093
+ if (!nodes_done) {
2094
+ throw FormatError("Section @nodes not found");
2095
+ }
2096
+
2097
+ if (!edges_done) {
2098
+ throw FormatError("Section @edges not found");
2099
+ }
2100
+
2101
+ if (!attributes_done && !_attributes.empty()) {
2102
+ throw FormatError("Section @attributes not found");
2103
+ }
2104
+
2105
+ }
2106
+
2107
+ /// @}
2108
+
2109
+ };
2110
+
2111
+ /// \ingroup lemon_io
2112
+ ///
2113
+ /// \brief Return a \ref lemon::GraphReader "GraphReader" class
2114
+ ///
2115
+ /// This function just returns a \ref lemon::GraphReader "GraphReader" class.
2116
+ ///
2117
+ /// With this function a graph can be read from an
2118
+ /// \ref lgf-format "LGF" file or input stream with several maps and
2119
+ /// attributes. For example, there is weighted matching problem on a
2120
+ /// graph, i.e. a graph with a \e weight map on the edges. This
2121
+ /// graph can be read with the following code:
2122
+ ///
2123
+ ///\code
2124
+ ///ListGraph graph;
2125
+ ///ListGraph::EdgeMap<int> weight(graph);
2126
+ ///graphReader(graph, std::cin).
2127
+ /// edgeMap("weight", weight).
2128
+ /// run();
2129
+ ///\endcode
2130
+ ///
2131
+ /// For a complete documentation, please see the
2132
+ /// \ref lemon::GraphReader "GraphReader"
2133
+ /// class documentation.
2134
+ /// \warning Don't forget to put the \ref lemon::GraphReader::run() "run()"
2135
+ /// to the end of the parameter list.
2136
+ /// \relates GraphReader
2137
+ /// \sa graphReader(TGR& graph, const std::string& fn)
2138
+ /// \sa graphReader(TGR& graph, const char* fn)
2139
+ template <typename TGR>
2140
+ GraphReader<TGR> graphReader(TGR& graph, std::istream& is) {
2141
+ GraphReader<TGR> tmp(graph, is);
2142
+ return tmp;
2143
+ }
2144
+
2145
+ /// \brief Return a \ref GraphReader class
2146
+ ///
2147
+ /// This function just returns a \ref GraphReader class.
2148
+ /// \relates GraphReader
2149
+ /// \sa graphReader(TGR& graph, std::istream& is)
2150
+ template <typename TGR>
2151
+ GraphReader<TGR> graphReader(TGR& graph, const std::string& fn) {
2152
+ GraphReader<TGR> tmp(graph, fn);
2153
+ return tmp;
2154
+ }
2155
+
2156
+ /// \brief Return a \ref GraphReader class
2157
+ ///
2158
+ /// This function just returns a \ref GraphReader class.
2159
+ /// \relates GraphReader
2160
+ /// \sa graphReader(TGR& graph, std::istream& is)
2161
+ template <typename TGR>
2162
+ GraphReader<TGR> graphReader(TGR& graph, const char* fn) {
2163
+ GraphReader<TGR> tmp(graph, fn);
2164
+ return tmp;
2165
+ }
2166
+
2167
+ template <typename BGR>
2168
+ class BpGraphReader;
2169
+
2170
+ template <typename TBGR>
2171
+ BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is = std::cin);
2172
+ template <typename TBGR>
2173
+ BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn);
2174
+ template <typename TBGR>
2175
+ BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn);
2176
+
2177
+ /// \ingroup lemon_io
2178
+ ///
2179
+ /// \brief \ref lgf-format "LGF" reader for bipartite graphs
2180
+ ///
2181
+ /// This utility reads an \ref lgf-format "LGF" file.
2182
+ ///
2183
+ /// It can be used almost the same way as \c GraphReader, but it
2184
+ /// reads the red and blue nodes from separate sections, and these
2185
+ /// sections can contain different set of maps.
2186
+ ///
2187
+ /// The red and blue node maps are read from the corresponding
2188
+ /// sections. If a map is defined with the same name in both of
2189
+ /// these sections, then it can be read as a node map.
2190
+ template <typename BGR>
2191
+ class BpGraphReader {
2192
+ public:
2193
+
2194
+ typedef BGR Graph;
2195
+
2196
+ private:
2197
+
2198
+ TEMPLATE_BPGRAPH_TYPEDEFS(BGR);
2199
+
2200
+ std::istream* _is;
2201
+ bool local_is;
2202
+ std::string _filename;
2203
+
2204
+ BGR& _graph;
2205
+
2206
+ std::string _nodes_caption;
2207
+ std::string _edges_caption;
2208
+ std::string _attributes_caption;
2209
+
2210
+ typedef std::map<std::string, RedNode> RedNodeIndex;
2211
+ RedNodeIndex _red_node_index;
2212
+ typedef std::map<std::string, BlueNode> BlueNodeIndex;
2213
+ BlueNodeIndex _blue_node_index;
2214
+ typedef std::map<std::string, Edge> EdgeIndex;
2215
+ EdgeIndex _edge_index;
2216
+
2217
+ typedef std::vector<std::pair<std::string,
2218
+ _reader_bits::MapStorageBase<RedNode>*> > RedNodeMaps;
2219
+ RedNodeMaps _red_node_maps;
2220
+ typedef std::vector<std::pair<std::string,
2221
+ _reader_bits::MapStorageBase<BlueNode>*> > BlueNodeMaps;
2222
+ BlueNodeMaps _blue_node_maps;
2223
+
2224
+ typedef std::vector<std::pair<std::string,
2225
+ _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
2226
+ EdgeMaps _edge_maps;
2227
+
2228
+ typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
2229
+ Attributes;
2230
+ Attributes _attributes;
2231
+
2232
+ bool _use_nodes;
2233
+ bool _use_edges;
2234
+
2235
+ bool _skip_nodes;
2236
+ bool _skip_edges;
2237
+
2238
+ int line_num;
2239
+ std::istringstream line;
2240
+
2241
+ public:
2242
+
2243
+ /// \brief Constructor
2244
+ ///
2245
+ /// Construct an undirected graph reader, which reads from the given
2246
+ /// input stream.
2247
+ BpGraphReader(BGR& graph, std::istream& is = std::cin)
2248
+ : _is(&is), local_is(false), _graph(graph),
2249
+ _use_nodes(false), _use_edges(false),
2250
+ _skip_nodes(false), _skip_edges(false) {}
2251
+
2252
+ /// \brief Constructor
2253
+ ///
2254
+ /// Construct an undirected graph reader, which reads from the given
2255
+ /// file.
2256
+ BpGraphReader(BGR& graph, const std::string& fn)
2257
+ : _is(new std::ifstream(fn.c_str())), local_is(true),
2258
+ _filename(fn), _graph(graph),
2259
+ _use_nodes(false), _use_edges(false),
2260
+ _skip_nodes(false), _skip_edges(false) {
2261
+ if (!(*_is)) {
2262
+ delete _is;
2263
+ throw IoError("Cannot open file", fn);
2264
+ }
2265
+ }
2266
+
2267
+ /// \brief Constructor
2268
+ ///
2269
+ /// Construct an undirected graph reader, which reads from the given
2270
+ /// file.
2271
+ BpGraphReader(BGR& graph, const char* fn)
2272
+ : _is(new std::ifstream(fn)), local_is(true),
2273
+ _filename(fn), _graph(graph),
2274
+ _use_nodes(false), _use_edges(false),
2275
+ _skip_nodes(false), _skip_edges(false) {
2276
+ if (!(*_is)) {
2277
+ delete _is;
2278
+ throw IoError("Cannot open file", fn);
2279
+ }
2280
+ }
2281
+
2282
+ /// \brief Destructor
2283
+ ~BpGraphReader() {
2284
+ for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
2285
+ it != _red_node_maps.end(); ++it) {
2286
+ delete it->second;
2287
+ }
2288
+
2289
+ for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
2290
+ it != _blue_node_maps.end(); ++it) {
2291
+ delete it->second;
2292
+ }
2293
+
2294
+ for (typename EdgeMaps::iterator it = _edge_maps.begin();
2295
+ it != _edge_maps.end(); ++it) {
2296
+ delete it->second;
2297
+ }
2298
+
2299
+ for (typename Attributes::iterator it = _attributes.begin();
2300
+ it != _attributes.end(); ++it) {
2301
+ delete it->second;
2302
+ }
2303
+
2304
+ if (local_is) {
2305
+ delete _is;
2306
+ }
2307
+
2308
+ }
2309
+
2310
+ private:
2311
+ template <typename TBGR>
2312
+ friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is);
2313
+ template <typename TBGR>
2314
+ friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph,
2315
+ const std::string& fn);
2316
+ template <typename TBGR>
2317
+ friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn);
2318
+
2319
+ BpGraphReader(BpGraphReader& other)
2320
+ : _is(other._is), local_is(other.local_is), _graph(other._graph),
2321
+ _use_nodes(other._use_nodes), _use_edges(other._use_edges),
2322
+ _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
2323
+
2324
+ other._is = 0;
2325
+ other.local_is = false;
2326
+
2327
+ _red_node_index.swap(other._red_node_index);
2328
+ _blue_node_index.swap(other._blue_node_index);
2329
+ _edge_index.swap(other._edge_index);
2330
+
2331
+ _red_node_maps.swap(other._red_node_maps);
2332
+ _blue_node_maps.swap(other._blue_node_maps);
2333
+ _edge_maps.swap(other._edge_maps);
2334
+ _attributes.swap(other._attributes);
2335
+
2336
+ _nodes_caption = other._nodes_caption;
2337
+ _edges_caption = other._edges_caption;
2338
+ _attributes_caption = other._attributes_caption;
2339
+
2340
+ }
2341
+
2342
+ BpGraphReader& operator=(const BpGraphReader&);
2343
+
2344
+ public:
2345
+
2346
+ /// \name Reading Rules
2347
+ /// @{
2348
+
2349
+ /// \brief Node map reading rule
2350
+ ///
2351
+ /// Add a node map reading rule to the reader.
2352
+ template <typename Map>
2353
+ BpGraphReader& nodeMap(const std::string& caption, Map& map) {
2354
+ checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
2355
+ _reader_bits::MapStorageBase<RedNode>* red_storage =
2356
+ new _reader_bits::MapStorage<RedNode, Map>(map);
2357
+ _red_node_maps.push_back(std::make_pair(caption, red_storage));
2358
+ _reader_bits::MapStorageBase<BlueNode>* blue_storage =
2359
+ new _reader_bits::MapStorage<BlueNode, Map>(map);
2360
+ _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
2361
+ return *this;
2362
+ }
2363
+
2364
+ /// \brief Node map reading rule
2365
+ ///
2366
+ /// Add a node map reading rule with specialized converter to the
2367
+ /// reader.
2368
+ template <typename Map, typename Converter>
2369
+ BpGraphReader& nodeMap(const std::string& caption, Map& map,
2370
+ const Converter& converter = Converter()) {
2371
+ checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
2372
+ _reader_bits::MapStorageBase<RedNode>* red_storage =
2373
+ new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter);
2374
+ _red_node_maps.push_back(std::make_pair(caption, red_storage));
2375
+ _reader_bits::MapStorageBase<BlueNode>* blue_storage =
2376
+ new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
2377
+ _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
2378
+ return *this;
2379
+ }
2380
+
2381
+ /// Add a red node map reading rule to the reader.
2382
+ template <typename Map>
2383
+ BpGraphReader& redNodeMap(const std::string& caption, Map& map) {
2384
+ checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>();
2385
+ _reader_bits::MapStorageBase<RedNode>* storage =
2386
+ new _reader_bits::MapStorage<RedNode, Map>(map);
2387
+ _red_node_maps.push_back(std::make_pair(caption, storage));
2388
+ return *this;
2389
+ }
2390
+
2391
+ /// \brief Red node map reading rule
2392
+ ///
2393
+ /// Add a red node map node reading rule with specialized converter to
2394
+ /// the reader.
2395
+ template <typename Map, typename Converter>
2396
+ BpGraphReader& redNodeMap(const std::string& caption, Map& map,
2397
+ const Converter& converter = Converter()) {
2398
+ checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>();
2399
+ _reader_bits::MapStorageBase<RedNode>* storage =
2400
+ new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter);
2401
+ _red_node_maps.push_back(std::make_pair(caption, storage));
2402
+ return *this;
2403
+ }
2404
+
2405
+ /// Add a blue node map reading rule to the reader.
2406
+ template <typename Map>
2407
+ BpGraphReader& blueNodeMap(const std::string& caption, Map& map) {
2408
+ checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>();
2409
+ _reader_bits::MapStorageBase<BlueNode>* storage =
2410
+ new _reader_bits::MapStorage<BlueNode, Map>(map);
2411
+ _blue_node_maps.push_back(std::make_pair(caption, storage));
2412
+ return *this;
2413
+ }
2414
+
2415
+ /// \brief Blue node map reading rule
2416
+ ///
2417
+ /// Add a blue node map reading rule with specialized converter to
2418
+ /// the reader.
2419
+ template <typename Map, typename Converter>
2420
+ BpGraphReader& blueNodeMap(const std::string& caption, Map& map,
2421
+ const Converter& converter = Converter()) {
2422
+ checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>();
2423
+ _reader_bits::MapStorageBase<BlueNode>* storage =
2424
+ new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
2425
+ _blue_node_maps.push_back(std::make_pair(caption, storage));
2426
+ return *this;
2427
+ }
2428
+
2429
+ /// \brief Edge map reading rule
2430
+ ///
2431
+ /// Add an edge map reading rule to the reader.
2432
+ template <typename Map>
2433
+ BpGraphReader& edgeMap(const std::string& caption, Map& map) {
2434
+ checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
2435
+ _reader_bits::MapStorageBase<Edge>* storage =
2436
+ new _reader_bits::MapStorage<Edge, Map>(map);
2437
+ _edge_maps.push_back(std::make_pair(caption, storage));
2438
+ return *this;
2439
+ }
2440
+
2441
+ /// \brief Edge map reading rule
2442
+ ///
2443
+ /// Add an edge map reading rule with specialized converter to the
2444
+ /// reader.
2445
+ template <typename Map, typename Converter>
2446
+ BpGraphReader& edgeMap(const std::string& caption, Map& map,
2447
+ const Converter& converter = Converter()) {
2448
+ checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
2449
+ _reader_bits::MapStorageBase<Edge>* storage =
2450
+ new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
2451
+ _edge_maps.push_back(std::make_pair(caption, storage));
2452
+ return *this;
2453
+ }
2454
+
2455
+ /// \brief Arc map reading rule
2456
+ ///
2457
+ /// Add an arc map reading rule to the reader.
2458
+ template <typename Map>
2459
+ BpGraphReader& arcMap(const std::string& caption, Map& map) {
2460
+ checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
2461
+ _reader_bits::MapStorageBase<Edge>* forward_storage =
2462
+ new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
2463
+ _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
2464
+ _reader_bits::MapStorageBase<Edge>* backward_storage =
2465
+ new _reader_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map);
2466
+ _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
2467
+ return *this;
2468
+ }
2469
+
2470
+ /// \brief Arc map reading rule
2471
+ ///
2472
+ /// Add an arc map reading rule with specialized converter to the
2473
+ /// reader.
2474
+ template <typename Map, typename Converter>
2475
+ BpGraphReader& arcMap(const std::string& caption, Map& map,
2476
+ const Converter& converter = Converter()) {
2477
+ checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
2478
+ _reader_bits::MapStorageBase<Edge>* forward_storage =
2479
+ new _reader_bits::GraphArcMapStorage<BGR, true, Map, Converter>
2480
+ (_graph, map, converter);
2481
+ _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
2482
+ _reader_bits::MapStorageBase<Edge>* backward_storage =
2483
+ new _reader_bits::GraphArcMapStorage<BGR, false, Map, Converter>
2484
+ (_graph, map, converter);
2485
+ _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
2486
+ return *this;
2487
+ }
2488
+
2489
+ /// \brief Attribute reading rule
2490
+ ///
2491
+ /// Add an attribute reading rule to the reader.
2492
+ template <typename Value>
2493
+ BpGraphReader& attribute(const std::string& caption, Value& value) {
2494
+ _reader_bits::ValueStorageBase* storage =
2495
+ new _reader_bits::ValueStorage<Value>(value);
2496
+ _attributes.insert(std::make_pair(caption, storage));
2497
+ return *this;
2498
+ }
2499
+
2500
+ /// \brief Attribute reading rule
2501
+ ///
2502
+ /// Add an attribute reading rule with specialized converter to the
2503
+ /// reader.
2504
+ template <typename Value, typename Converter>
2505
+ BpGraphReader& attribute(const std::string& caption, Value& value,
2506
+ const Converter& converter = Converter()) {
2507
+ _reader_bits::ValueStorageBase* storage =
2508
+ new _reader_bits::ValueStorage<Value, Converter>(value, converter);
2509
+ _attributes.insert(std::make_pair(caption, storage));
2510
+ return *this;
2511
+ }
2512
+
2513
+ /// \brief Node reading rule
2514
+ ///
2515
+ /// Add a node reading rule to reader.
2516
+ BpGraphReader& node(const std::string& caption, Node& node) {
2517
+ typedef _reader_bits::DoubleMapLookUpConverter<
2518
+ Node, RedNodeIndex, BlueNodeIndex> Converter;
2519
+ Converter converter(_red_node_index, _blue_node_index);
2520
+ _reader_bits::ValueStorageBase* storage =
2521
+ new _reader_bits::ValueStorage<Node, Converter>(node, converter);
2522
+ _attributes.insert(std::make_pair(caption, storage));
2523
+ return *this;
2524
+ }
2525
+
2526
+ /// \brief Red node reading rule
2527
+ ///
2528
+ /// Add a red node reading rule to reader.
2529
+ BpGraphReader& redNode(const std::string& caption, RedNode& node) {
2530
+ typedef _reader_bits::MapLookUpConverter<RedNode> Converter;
2531
+ Converter converter(_red_node_index);
2532
+ _reader_bits::ValueStorageBase* storage =
2533
+ new _reader_bits::ValueStorage<RedNode, Converter>(node, converter);
2534
+ _attributes.insert(std::make_pair(caption, storage));
2535
+ return *this;
2536
+ }
2537
+
2538
+ /// \brief Blue node reading rule
2539
+ ///
2540
+ /// Add a blue node reading rule to reader.
2541
+ BpGraphReader& blueNode(const std::string& caption, BlueNode& node) {
2542
+ typedef _reader_bits::MapLookUpConverter<BlueNode> Converter;
2543
+ Converter converter(_blue_node_index);
2544
+ _reader_bits::ValueStorageBase* storage =
2545
+ new _reader_bits::ValueStorage<BlueNode, Converter>(node, converter);
2546
+ _attributes.insert(std::make_pair(caption, storage));
2547
+ return *this;
2548
+ }
2549
+
2550
+ /// \brief Edge reading rule
2551
+ ///
2552
+ /// Add an edge reading rule to reader.
2553
+ BpGraphReader& edge(const std::string& caption, Edge& edge) {
2554
+ typedef _reader_bits::MapLookUpConverter<Edge> Converter;
2555
+ Converter converter(_edge_index);
2556
+ _reader_bits::ValueStorageBase* storage =
2557
+ new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
2558
+ _attributes.insert(std::make_pair(caption, storage));
2559
+ return *this;
2560
+ }
2561
+
2562
+ /// \brief Arc reading rule
2563
+ ///
2564
+ /// Add an arc reading rule to reader.
2565
+ BpGraphReader& arc(const std::string& caption, Arc& arc) {
2566
+ typedef _reader_bits::GraphArcLookUpConverter<BGR> Converter;
2567
+ Converter converter(_graph, _edge_index);
2568
+ _reader_bits::ValueStorageBase* storage =
2569
+ new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
2570
+ _attributes.insert(std::make_pair(caption, storage));
2571
+ return *this;
2572
+ }
2573
+
2574
+ /// @}
2575
+
2576
+ /// \name Select Section by Name
2577
+ /// @{
2578
+
2579
+ /// \brief Set \c \@nodes section to be read
2580
+ ///
2581
+ /// Set \c \@nodes section to be read.
2582
+ BpGraphReader& nodes(const std::string& caption) {
2583
+ _nodes_caption = caption;
2584
+ return *this;
2585
+ }
2586
+
2587
+ /// \brief Set \c \@edges section to be read
2588
+ ///
2589
+ /// Set \c \@edges section to be read.
2590
+ BpGraphReader& edges(const std::string& caption) {
2591
+ _edges_caption = caption;
2592
+ return *this;
2593
+ }
2594
+
2595
+ /// \brief Set \c \@attributes section to be read
2596
+ ///
2597
+ /// Set \c \@attributes section to be read.
2598
+ BpGraphReader& attributes(const std::string& caption) {
2599
+ _attributes_caption = caption;
2600
+ return *this;
2601
+ }
2602
+
2603
+ /// @}
2604
+
2605
+ /// \name Using Previously Constructed Node or Edge Set
2606
+ /// @{
2607
+
2608
+ /// \brief Use previously constructed node set
2609
+ ///
2610
+ /// Use previously constructed node set, and specify the node
2611
+ /// label map.
2612
+ template <typename Map>
2613
+ BpGraphReader& useNodes(const Map& map) {
2614
+ checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
2615
+ LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
2616
+ _use_nodes = true;
2617
+ _writer_bits::DefaultConverter<typename Map::Value> converter;
2618
+ for (RedNodeIt n(_graph); n != INVALID; ++n) {
2619
+ _red_node_index.insert(std::make_pair(converter(map[n]), n));
2620
+ }
2621
+ for (BlueNodeIt n(_graph); n != INVALID; ++n) {
2622
+ _blue_node_index.insert(std::make_pair(converter(map[n]), n));
2623
+ }
2624
+ return *this;
2625
+ }
2626
+
2627
+ /// \brief Use previously constructed node set
2628
+ ///
2629
+ /// Use previously constructed node set, and specify the node
2630
+ /// label map and a functor which converts the label map values to
2631
+ /// \c std::string.
2632
+ template <typename Map, typename Converter>
2633
+ BpGraphReader& useNodes(const Map& map,
2634
+ const Converter& converter = Converter()) {
2635
+ checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
2636
+ LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
2637
+ _use_nodes = true;
2638
+ for (RedNodeIt n(_graph); n != INVALID; ++n) {
2639
+ _red_node_index.insert(std::make_pair(converter(map[n]), n));
2640
+ }
2641
+ for (BlueNodeIt n(_graph); n != INVALID; ++n) {
2642
+ _blue_node_index.insert(std::make_pair(converter(map[n]), n));
2643
+ }
2644
+ return *this;
2645
+ }
2646
+
2647
+ /// \brief Use previously constructed edge set
2648
+ ///
2649
+ /// Use previously constructed edge set, and specify the edge
2650
+ /// label map.
2651
+ template <typename Map>
2652
+ BpGraphReader& useEdges(const Map& map) {
2653
+ checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
2654
+ LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
2655
+ _use_edges = true;
2656
+ _writer_bits::DefaultConverter<typename Map::Value> converter;
2657
+ for (EdgeIt a(_graph); a != INVALID; ++a) {
2658
+ _edge_index.insert(std::make_pair(converter(map[a]), a));
2659
+ }
2660
+ return *this;
2661
+ }
2662
+
2663
+ /// \brief Use previously constructed edge set
2664
+ ///
2665
+ /// Use previously constructed edge set, and specify the edge
2666
+ /// label map and a functor which converts the label map values to
2667
+ /// \c std::string.
2668
+ template <typename Map, typename Converter>
2669
+ BpGraphReader& useEdges(const Map& map,
2670
+ const Converter& converter = Converter()) {
2671
+ checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
2672
+ LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
2673
+ _use_edges = true;
2674
+ for (EdgeIt a(_graph); a != INVALID; ++a) {
2675
+ _edge_index.insert(std::make_pair(converter(map[a]), a));
2676
+ }
2677
+ return *this;
2678
+ }
2679
+
2680
+ /// \brief Skip the reading of node section
2681
+ ///
2682
+ /// Omit the reading of the node section. This implies that each node
2683
+ /// map reading rule will be abandoned, and the nodes of the graph
2684
+ /// will not be constructed, which usually cause that the edge set
2685
+ /// could not be read due to lack of node name
2686
+ /// could not be read due to lack of node name resolving.
2687
+ /// Therefore \c skipEdges() function should also be used, or
2688
+ /// \c useNodes() should be used to specify the label of the nodes.
2689
+ BpGraphReader& skipNodes() {
2690
+ LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
2691
+ _skip_nodes = true;
2692
+ return *this;
2693
+ }
2694
+
2695
+ /// \brief Skip the reading of edge section
2696
+ ///
2697
+ /// Omit the reading of the edge section. This implies that each edge
2698
+ /// map reading rule will be abandoned, and the edges of the graph
2699
+ /// will not be constructed.
2700
+ BpGraphReader& skipEdges() {
2701
+ LEMON_ASSERT(!_skip_edges, "Skip edges already set");
2702
+ _skip_edges = true;
2703
+ return *this;
2704
+ }
2705
+
2706
+ /// @}
2707
+
2708
+ private:
2709
+
2710
+ bool readLine() {
2711
+ std::string str;
2712
+ while(++line_num, std::getline(*_is, str)) {
2713
+ line.clear(); line.str(str);
2714
+ char c;
2715
+ if (line >> std::ws >> c && c != '#') {
2716
+ line.putback(c);
2717
+ return true;
2718
+ }
2719
+ }
2720
+ return false;
2721
+ }
2722
+
2723
+ bool readSuccess() {
2724
+ return static_cast<bool>(*_is);
2725
+ }
2726
+
2727
+ void skipSection() {
2728
+ char c;
2729
+ while (readSuccess() && line >> c && c != '@') {
2730
+ readLine();
2731
+ }
2732
+ if (readSuccess()) {
2733
+ line.putback(c);
2734
+ }
2735
+ }
2736
+
2737
+ void readRedNodes() {
2738
+
2739
+ std::vector<int> map_index(_red_node_maps.size());
2740
+ int map_num, label_index;
2741
+
2742
+ char c;
2743
+ if (!readLine() || !(line >> c) || c == '@') {
2744
+ if (readSuccess() && line) line.putback(c);
2745
+ if (!_red_node_maps.empty())
2746
+ throw FormatError("Cannot find map names");
2747
+ return;
2748
+ }
2749
+ line.putback(c);
2750
+
2751
+ {
2752
+ std::map<std::string, int> maps;
2753
+
2754
+ std::string map;
2755
+ int index = 0;
2756
+ while (_reader_bits::readToken(line, map)) {
2757
+ if (maps.find(map) != maps.end()) {
2758
+ std::ostringstream msg;
2759
+ msg << "Multiple occurence of red node map: " << map;
2760
+ throw FormatError(msg.str());
2761
+ }
2762
+ maps.insert(std::make_pair(map, index));
2763
+ ++index;
2764
+ }
2765
+
2766
+ for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) {
2767
+ std::map<std::string, int>::iterator jt =
2768
+ maps.find(_red_node_maps[i].first);
2769
+ if (jt == maps.end()) {
2770
+ std::ostringstream msg;
2771
+ msg << "Map not found: " << _red_node_maps[i].first;
2772
+ throw FormatError(msg.str());
2773
+ }
2774
+ map_index[i] = jt->second;
2775
+ }
2776
+
2777
+ {
2778
+ std::map<std::string, int>::iterator jt = maps.find("label");
2779
+ if (jt != maps.end()) {
2780
+ label_index = jt->second;
2781
+ } else {
2782
+ label_index = -1;
2783
+ }
2784
+ }
2785
+ map_num = maps.size();
2786
+ }
2787
+
2788
+ while (readLine() && line >> c && c != '@') {
2789
+ line.putback(c);
2790
+
2791
+ std::vector<std::string> tokens(map_num);
2792
+ for (int i = 0; i < map_num; ++i) {
2793
+ if (!_reader_bits::readToken(line, tokens[i])) {
2794
+ std::ostringstream msg;
2795
+ msg << "Column not found (" << i + 1 << ")";
2796
+ throw FormatError(msg.str());
2797
+ }
2798
+ }
2799
+ if (line >> std::ws >> c)
2800
+ throw FormatError("Extra character at the end of line");
2801
+
2802
+ RedNode n;
2803
+ if (!_use_nodes) {
2804
+ n = _graph.addRedNode();
2805
+ if (label_index != -1)
2806
+ _red_node_index.insert(std::make_pair(tokens[label_index], n));
2807
+ } else {
2808
+ if (label_index == -1)
2809
+ throw FormatError("Label map not found");
2810
+ typename std::map<std::string, RedNode>::iterator it =
2811
+ _red_node_index.find(tokens[label_index]);
2812
+ if (it == _red_node_index.end()) {
2813
+ std::ostringstream msg;
2814
+ msg << "Node with label not found: " << tokens[label_index];
2815
+ throw FormatError(msg.str());
2816
+ }
2817
+ n = it->second;
2818
+ }
2819
+
2820
+ for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) {
2821
+ _red_node_maps[i].second->set(n, tokens[map_index[i]]);
2822
+ }
2823
+
2824
+ }
2825
+ if (readSuccess()) {
2826
+ line.putback(c);
2827
+ }
2828
+ }
2829
+
2830
+ void readBlueNodes() {
2831
+
2832
+ std::vector<int> map_index(_blue_node_maps.size());
2833
+ int map_num, label_index;
2834
+
2835
+ char c;
2836
+ if (!readLine() || !(line >> c) || c == '@') {
2837
+ if (readSuccess() && line) line.putback(c);
2838
+ if (!_blue_node_maps.empty())
2839
+ throw FormatError("Cannot find map names");
2840
+ return;
2841
+ }
2842
+ line.putback(c);
2843
+
2844
+ {
2845
+ std::map<std::string, int> maps;
2846
+
2847
+ std::string map;
2848
+ int index = 0;
2849
+ while (_reader_bits::readToken(line, map)) {
2850
+ if (maps.find(map) != maps.end()) {
2851
+ std::ostringstream msg;
2852
+ msg << "Multiple occurence of blue node map: " << map;
2853
+ throw FormatError(msg.str());
2854
+ }
2855
+ maps.insert(std::make_pair(map, index));
2856
+ ++index;
2857
+ }
2858
+
2859
+ for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) {
2860
+ std::map<std::string, int>::iterator jt =
2861
+ maps.find(_blue_node_maps[i].first);
2862
+ if (jt == maps.end()) {
2863
+ std::ostringstream msg;
2864
+ msg << "Map not found: " << _blue_node_maps[i].first;
2865
+ throw FormatError(msg.str());
2866
+ }
2867
+ map_index[i] = jt->second;
2868
+ }
2869
+
2870
+ {
2871
+ std::map<std::string, int>::iterator jt = maps.find("label");
2872
+ if (jt != maps.end()) {
2873
+ label_index = jt->second;
2874
+ } else {
2875
+ label_index = -1;
2876
+ }
2877
+ }
2878
+ map_num = maps.size();
2879
+ }
2880
+
2881
+ while (readLine() && line >> c && c != '@') {
2882
+ line.putback(c);
2883
+
2884
+ std::vector<std::string> tokens(map_num);
2885
+ for (int i = 0; i < map_num; ++i) {
2886
+ if (!_reader_bits::readToken(line, tokens[i])) {
2887
+ std::ostringstream msg;
2888
+ msg << "Column not found (" << i + 1 << ")";
2889
+ throw FormatError(msg.str());
2890
+ }
2891
+ }
2892
+ if (line >> std::ws >> c)
2893
+ throw FormatError("Extra character at the end of line");
2894
+
2895
+ BlueNode n;
2896
+ if (!_use_nodes) {
2897
+ n = _graph.addBlueNode();
2898
+ if (label_index != -1)
2899
+ _blue_node_index.insert(std::make_pair(tokens[label_index], n));
2900
+ } else {
2901
+ if (label_index == -1)
2902
+ throw FormatError("Label map not found");
2903
+ typename std::map<std::string, BlueNode>::iterator it =
2904
+ _blue_node_index.find(tokens[label_index]);
2905
+ if (it == _blue_node_index.end()) {
2906
+ std::ostringstream msg;
2907
+ msg << "Node with label not found: " << tokens[label_index];
2908
+ throw FormatError(msg.str());
2909
+ }
2910
+ n = it->second;
2911
+ }
2912
+
2913
+ for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) {
2914
+ _blue_node_maps[i].second->set(n, tokens[map_index[i]]);
2915
+ }
2916
+
2917
+ }
2918
+ if (readSuccess()) {
2919
+ line.putback(c);
2920
+ }
2921
+ }
2922
+
2923
+ void readEdges() {
2924
+
2925
+ std::vector<int> map_index(_edge_maps.size());
2926
+ int map_num, label_index;
2927
+
2928
+ char c;
2929
+ if (!readLine() || !(line >> c) || c == '@') {
2930
+ if (readSuccess() && line) line.putback(c);
2931
+ if (!_edge_maps.empty())
2932
+ throw FormatError("Cannot find map names");
2933
+ return;
2934
+ }
2935
+ line.putback(c);
2936
+
2937
+ {
2938
+ std::map<std::string, int> maps;
2939
+
2940
+ std::string map;
2941
+ int index = 0;
2942
+ while (_reader_bits::readToken(line, map)) {
2943
+ if (maps.find(map) != maps.end()) {
2944
+ std::ostringstream msg;
2945
+ msg << "Multiple occurence of edge map: " << map;
2946
+ throw FormatError(msg.str());
2947
+ }
2948
+ maps.insert(std::make_pair(map, index));
2949
+ ++index;
2950
+ }
2951
+
2952
+ for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
2953
+ std::map<std::string, int>::iterator jt =
2954
+ maps.find(_edge_maps[i].first);
2955
+ if (jt == maps.end()) {
2956
+ std::ostringstream msg;
2957
+ msg << "Map not found: " << _edge_maps[i].first;
2958
+ throw FormatError(msg.str());
2959
+ }
2960
+ map_index[i] = jt->second;
2961
+ }
2962
+
2963
+ {
2964
+ std::map<std::string, int>::iterator jt = maps.find("label");
2965
+ if (jt != maps.end()) {
2966
+ label_index = jt->second;
2967
+ } else {
2968
+ label_index = -1;
2969
+ }
2970
+ }
2971
+ map_num = maps.size();
2972
+ }
2973
+
2974
+ while (readLine() && line >> c && c != '@') {
2975
+ line.putback(c);
2976
+
2977
+ std::string source_token;
2978
+ std::string target_token;
2979
+
2980
+ if (!_reader_bits::readToken(line, source_token))
2981
+ throw FormatError("Red node not found");
2982
+
2983
+ if (!_reader_bits::readToken(line, target_token))
2984
+ throw FormatError("Blue node not found");
2985
+
2986
+ std::vector<std::string> tokens(map_num);
2987
+ for (int i = 0; i < map_num; ++i) {
2988
+ if (!_reader_bits::readToken(line, tokens[i])) {
2989
+ std::ostringstream msg;
2990
+ msg << "Column not found (" << i + 1 << ")";
2991
+ throw FormatError(msg.str());
2992
+ }
2993
+ }
2994
+ if (line >> std::ws >> c)
2995
+ throw FormatError("Extra character at the end of line");
2996
+
2997
+ Edge e;
2998
+ if (!_use_edges) {
2999
+ typename RedNodeIndex::iterator rit =
3000
+ _red_node_index.find(source_token);
3001
+ if (rit == _red_node_index.end()) {
3002
+ std::ostringstream msg;
3003
+ msg << "Item not found: " << source_token;
3004
+ throw FormatError(msg.str());
3005
+ }
3006
+ RedNode source = rit->second;
3007
+ typename BlueNodeIndex::iterator it =
3008
+ _blue_node_index.find(target_token);
3009
+ if (it == _blue_node_index.end()) {
3010
+ std::ostringstream msg;
3011
+ msg << "Item not found: " << target_token;
3012
+ throw FormatError(msg.str());
3013
+ }
3014
+ BlueNode target = it->second;
3015
+
3016
+ // It is checked that source is red and
3017
+ // target is blue, so this should be safe:
3018
+ e = _graph.addEdge(source, target);
3019
+ if (label_index != -1)
3020
+ _edge_index.insert(std::make_pair(tokens[label_index], e));
3021
+ } else {
3022
+ if (label_index == -1)
3023
+ throw FormatError("Label map not found");
3024
+ typename std::map<std::string, Edge>::iterator it =
3025
+ _edge_index.find(tokens[label_index]);
3026
+ if (it == _edge_index.end()) {
3027
+ std::ostringstream msg;
3028
+ msg << "Edge with label not found: " << tokens[label_index];
3029
+ throw FormatError(msg.str());
3030
+ }
3031
+ e = it->second;
3032
+ }
3033
+
3034
+ for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
3035
+ _edge_maps[i].second->set(e, tokens[map_index[i]]);
3036
+ }
3037
+
3038
+ }
3039
+ if (readSuccess()) {
3040
+ line.putback(c);
3041
+ }
3042
+ }
3043
+
3044
+ void readAttributes() {
3045
+
3046
+ std::set<std::string> read_attr;
3047
+
3048
+ char c;
3049
+ while (readLine() && line >> c && c != '@') {
3050
+ line.putback(c);
3051
+
3052
+ std::string attr, token;
3053
+ if (!_reader_bits::readToken(line, attr))
3054
+ throw FormatError("Attribute name not found");
3055
+ if (!_reader_bits::readToken(line, token))
3056
+ throw FormatError("Attribute value not found");
3057
+ if (line >> c)
3058
+ throw FormatError("Extra character at the end of line");
3059
+
3060
+ {
3061
+ std::set<std::string>::iterator it = read_attr.find(attr);
3062
+ if (it != read_attr.end()) {
3063
+ std::ostringstream msg;
3064
+ msg << "Multiple occurence of attribute: " << attr;
3065
+ throw FormatError(msg.str());
3066
+ }
3067
+ read_attr.insert(attr);
3068
+ }
3069
+
3070
+ {
3071
+ typename Attributes::iterator it = _attributes.lower_bound(attr);
3072
+ while (it != _attributes.end() && it->first == attr) {
3073
+ it->second->set(token);
3074
+ ++it;
3075
+ }
3076
+ }
3077
+
3078
+ }
3079
+ if (readSuccess()) {
3080
+ line.putback(c);
3081
+ }
3082
+ for (typename Attributes::iterator it = _attributes.begin();
3083
+ it != _attributes.end(); ++it) {
3084
+ if (read_attr.find(it->first) == read_attr.end()) {
3085
+ std::ostringstream msg;
3086
+ msg << "Attribute not found: " << it->first;
3087
+ throw FormatError(msg.str());
3088
+ }
3089
+ }
3090
+ }
3091
+
3092
+ public:
3093
+
3094
+ /// \name Execution of the Reader
3095
+ /// @{
3096
+
3097
+ /// \brief Start the batch processing
3098
+ ///
3099
+ /// This function starts the batch processing
3100
+ void run() {
3101
+
3102
+ LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
3103
+
3104
+ bool red_nodes_done = _skip_nodes;
3105
+ bool blue_nodes_done = _skip_nodes;
3106
+ bool edges_done = _skip_edges;
3107
+ bool attributes_done = false;
3108
+
3109
+ line_num = 0;
3110
+ readLine();
3111
+ skipSection();
3112
+
3113
+ while (readSuccess()) {
3114
+ try {
3115
+ char c;
3116
+ std::string section, caption;
3117
+ line >> c;
3118
+ _reader_bits::readToken(line, section);
3119
+ _reader_bits::readToken(line, caption);
3120
+
3121
+ if (line >> c)
3122
+ throw FormatError("Extra character at the end of line");
3123
+
3124
+ if (section == "red_nodes" && !red_nodes_done) {
3125
+ if (_nodes_caption.empty() || _nodes_caption == caption) {
3126
+ readRedNodes();
3127
+ red_nodes_done = true;
3128
+ }
3129
+ } else if (section == "blue_nodes" && !blue_nodes_done) {
3130
+ if (_nodes_caption.empty() || _nodes_caption == caption) {
3131
+ readBlueNodes();
3132
+ blue_nodes_done = true;
3133
+ }
3134
+ } else if ((section == "edges" || section == "arcs") &&
3135
+ !edges_done) {
3136
+ if (_edges_caption.empty() || _edges_caption == caption) {
3137
+ readEdges();
3138
+ edges_done = true;
3139
+ }
3140
+ } else if (section == "attributes" && !attributes_done) {
3141
+ if (_attributes_caption.empty() || _attributes_caption == caption) {
3142
+ readAttributes();
3143
+ attributes_done = true;
3144
+ }
3145
+ } else {
3146
+ readLine();
3147
+ skipSection();
3148
+ }
3149
+ } catch (FormatError& error) {
3150
+ error.line(line_num);
3151
+ error.file(_filename);
3152
+ throw;
3153
+ }
3154
+ }
3155
+
3156
+ if (!red_nodes_done) {
3157
+ throw FormatError("Section @red_nodes not found");
3158
+ }
3159
+
3160
+ if (!blue_nodes_done) {
3161
+ throw FormatError("Section @blue_nodes not found");
3162
+ }
3163
+
3164
+ if (!edges_done) {
3165
+ throw FormatError("Section @edges not found");
3166
+ }
3167
+
3168
+ if (!attributes_done && !_attributes.empty()) {
3169
+ throw FormatError("Section @attributes not found");
3170
+ }
3171
+
3172
+ }
3173
+
3174
+ /// @}
3175
+
3176
+ };
3177
+
3178
+ /// \ingroup lemon_io
3179
+ ///
3180
+ /// \brief Return a \ref lemon::BpGraphReader "BpGraphReader" class
3181
+ ///
3182
+ /// This function just returns a \ref lemon::BpGraphReader
3183
+ /// "BpGraphReader" class.
3184
+ ///
3185
+ /// With this function a graph can be read from an
3186
+ /// \ref lgf-format "LGF" file or input stream with several maps and
3187
+ /// attributes. For example, there is bipartite weighted matching problem
3188
+ /// on a graph, i.e. a graph with a \e weight map on the edges. This
3189
+ /// graph can be read with the following code:
3190
+ ///
3191
+ ///\code
3192
+ ///ListBpGraph graph;
3193
+ ///ListBpGraph::EdgeMap<int> weight(graph);
3194
+ ///bpGraphReader(graph, std::cin).
3195
+ /// edgeMap("weight", weight).
3196
+ /// run();
3197
+ ///\endcode
3198
+ ///
3199
+ /// For a complete documentation, please see the
3200
+ /// \ref lemon::BpGraphReader "BpGraphReader"
3201
+ /// class documentation.
3202
+ /// \warning Don't forget to put the \ref lemon::BpGraphReader::run() "run()"
3203
+ /// to the end of the parameter list.
3204
+ /// \relates BpGraphReader
3205
+ /// \sa bpGraphReader(TBGR& graph, const std::string& fn)
3206
+ /// \sa bpGraphReader(TBGR& graph, const char* fn)
3207
+ template <typename TBGR>
3208
+ BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is) {
3209
+ BpGraphReader<TBGR> tmp(graph, is);
3210
+ return tmp;
3211
+ }
3212
+
3213
+ /// \brief Return a \ref BpGraphReader class
3214
+ ///
3215
+ /// This function just returns a \ref BpGraphReader class.
3216
+ /// \relates BpGraphReader
3217
+ /// \sa bpGraphReader(TBGR& graph, std::istream& is)
3218
+ template <typename TBGR>
3219
+ BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn) {
3220
+ BpGraphReader<TBGR> tmp(graph, fn);
3221
+ return tmp;
3222
+ }
3223
+
3224
+ /// \brief Return a \ref BpGraphReader class
3225
+ ///
3226
+ /// This function just returns a \ref BpGraphReader class.
3227
+ /// \relates BpGraphReader
3228
+ /// \sa bpGraphReader(TBGR& graph, std::istream& is)
3229
+ template <typename TBGR>
3230
+ BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char* fn) {
3231
+ BpGraphReader<TBGR> tmp(graph, fn);
3232
+ return tmp;
3233
+ }
3234
+
3235
+ class SectionReader;
3236
+
3237
+ SectionReader sectionReader(std::istream& is);
3238
+ SectionReader sectionReader(const std::string& fn);
3239
+ SectionReader sectionReader(const char* fn);
3240
+
3241
+ /// \ingroup lemon_io
3242
+ ///
3243
+ /// \brief Section reader class
3244
+ ///
3245
+ /// In the \ref lgf-format "LGF" file extra sections can be placed,
3246
+ /// which contain any data in arbitrary format. Such sections can be
3247
+ /// read with this class. A reading rule can be added to the class
3248
+ /// with two different functions. With the \c sectionLines() function a
3249
+ /// functor can process the section line-by-line, while with the \c
3250
+ /// sectionStream() member the section can be read from an input
3251
+ /// stream.
3252
+ class SectionReader {
3253
+ private:
3254
+
3255
+ std::istream* _is;
3256
+ bool local_is;
3257
+ std::string _filename;
3258
+
3259
+ typedef std::map<std::string, _reader_bits::Section*> Sections;
3260
+ Sections _sections;
3261
+
3262
+ int line_num;
3263
+ std::istringstream line;
3264
+
3265
+ public:
3266
+
3267
+ /// \brief Constructor
3268
+ ///
3269
+ /// Construct a section reader, which reads from the given input
3270
+ /// stream.
3271
+ SectionReader(std::istream& is)
3272
+ : _is(&is), local_is(false) {}
3273
+
3274
+ /// \brief Constructor
3275
+ ///
3276
+ /// Construct a section reader, which reads from the given file.
3277
+ SectionReader(const std::string& fn)
3278
+ : _is(new std::ifstream(fn.c_str())), local_is(true),
3279
+ _filename(fn) {
3280
+ if (!(*_is)) {
3281
+ delete _is;
3282
+ throw IoError("Cannot open file", fn);
3283
+ }
3284
+ }
3285
+
3286
+ /// \brief Constructor
3287
+ ///
3288
+ /// Construct a section reader, which reads from the given file.
3289
+ SectionReader(const char* fn)
3290
+ : _is(new std::ifstream(fn)), local_is(true),
3291
+ _filename(fn) {
3292
+ if (!(*_is)) {
3293
+ delete _is;
3294
+ throw IoError("Cannot open file", fn);
3295
+ }
3296
+ }
3297
+
3298
+ /// \brief Destructor
3299
+ ~SectionReader() {
3300
+ for (Sections::iterator it = _sections.begin();
3301
+ it != _sections.end(); ++it) {
3302
+ delete it->second;
3303
+ }
3304
+
3305
+ if (local_is) {
3306
+ delete _is;
3307
+ }
3308
+
3309
+ }
3310
+
3311
+ private:
3312
+
3313
+ friend SectionReader sectionReader(std::istream& is);
3314
+ friend SectionReader sectionReader(const std::string& fn);
3315
+ friend SectionReader sectionReader(const char* fn);
3316
+
3317
+ SectionReader(SectionReader& other)
3318
+ : _is(other._is), local_is(other.local_is) {
3319
+
3320
+ other._is = 0;
3321
+ other.local_is = false;
3322
+
3323
+ _sections.swap(other._sections);
3324
+ }
3325
+
3326
+ SectionReader& operator=(const SectionReader&);
3327
+
3328
+ public:
3329
+
3330
+ /// \name Section Readers
3331
+ /// @{
3332
+
3333
+ /// \brief Add a section processor with line oriented reading
3334
+ ///
3335
+ /// The first parameter is the type descriptor of the section, the
3336
+ /// second is a functor, which takes just one \c std::string
3337
+ /// parameter. At the reading process, each line of the section
3338
+ /// will be given to the functor object. However, the empty lines
3339
+ /// and the comment lines are filtered out, and the leading
3340
+ /// whitespaces are trimmed from each processed string.
3341
+ ///
3342
+ /// For example, let's see a section, which contain several
3343
+ /// integers, which should be inserted into a vector.
3344
+ ///\code
3345
+ /// @numbers
3346
+ /// 12 45 23
3347
+ /// 4
3348
+ /// 23 6
3349
+ ///\endcode
3350
+ ///
3351
+ /// The functor is implemented as a struct:
3352
+ ///\code
3353
+ /// struct NumberSection {
3354
+ /// std::vector<int>& _data;
3355
+ /// NumberSection(std::vector<int>& data) : _data(data) {}
3356
+ /// void operator()(const std::string& line) {
3357
+ /// std::istringstream ls(line);
3358
+ /// int value;
3359
+ /// while (ls >> value) _data.push_back(value);
3360
+ /// }
3361
+ /// };
3362
+ ///
3363
+ /// // ...
3364
+ ///
3365
+ /// reader.sectionLines("numbers", NumberSection(vec));
3366
+ ///\endcode
3367
+ template <typename Functor>
3368
+ SectionReader& sectionLines(const std::string& type, Functor functor) {
3369
+ LEMON_ASSERT(!type.empty(), "Type is empty.");
3370
+ LEMON_ASSERT(_sections.find(type) == _sections.end(),
3371
+ "Multiple reading of section.");
3372
+ _sections.insert(std::make_pair(type,
3373
+ new _reader_bits::LineSection<Functor>(functor)));
3374
+ return *this;
3375
+ }
3376
+
3377
+
3378
+ /// \brief Add a section processor with stream oriented reading
3379
+ ///
3380
+ /// The first parameter is the type of the section, the second is
3381
+ /// a functor, which takes an \c std::istream& and an \c int&
3382
+ /// parameter, the latter regard to the line number of stream. The
3383
+ /// functor can read the input while the section go on, and the
3384
+ /// line number should be modified accordingly.
3385
+ template <typename Functor>
3386
+ SectionReader& sectionStream(const std::string& type, Functor functor) {
3387
+ LEMON_ASSERT(!type.empty(), "Type is empty.");
3388
+ LEMON_ASSERT(_sections.find(type) == _sections.end(),
3389
+ "Multiple reading of section.");
3390
+ _sections.insert(std::make_pair(type,
3391
+ new _reader_bits::StreamSection<Functor>(functor)));
3392
+ return *this;
3393
+ }
3394
+
3395
+ /// @}
3396
+
3397
+ private:
3398
+
3399
+ bool readLine() {
3400
+ std::string str;
3401
+ while(++line_num, std::getline(*_is, str)) {
3402
+ line.clear(); line.str(str);
3403
+ char c;
3404
+ if (line >> std::ws >> c && c != '#') {
3405
+ line.putback(c);
3406
+ return true;
3407
+ }
3408
+ }
3409
+ return false;
3410
+ }
3411
+
3412
+ bool readSuccess() {
3413
+ return static_cast<bool>(*_is);
3414
+ }
3415
+
3416
+ void skipSection() {
3417
+ char c;
3418
+ while (readSuccess() && line >> c && c != '@') {
3419
+ readLine();
3420
+ }
3421
+ if (readSuccess()) {
3422
+ line.putback(c);
3423
+ }
3424
+ }
3425
+
3426
+ public:
3427
+
3428
+
3429
+ /// \name Execution of the Reader
3430
+ /// @{
3431
+
3432
+ /// \brief Start the batch processing
3433
+ ///
3434
+ /// This function starts the batch processing.
3435
+ void run() {
3436
+
3437
+ LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
3438
+
3439
+ std::set<std::string> extra_sections;
3440
+
3441
+ line_num = 0;
3442
+ readLine();
3443
+ skipSection();
3444
+
3445
+ while (readSuccess()) {
3446
+ try {
3447
+ char c;
3448
+ std::string section, caption;
3449
+ line >> c;
3450
+ _reader_bits::readToken(line, section);
3451
+ _reader_bits::readToken(line, caption);
3452
+
3453
+ if (line >> c)
3454
+ throw FormatError("Extra character at the end of line");
3455
+
3456
+ if (extra_sections.find(section) != extra_sections.end()) {
3457
+ std::ostringstream msg;
3458
+ msg << "Multiple occurence of section: " << section;
3459
+ throw FormatError(msg.str());
3460
+ }
3461
+ Sections::iterator it = _sections.find(section);
3462
+ if (it != _sections.end()) {
3463
+ extra_sections.insert(section);
3464
+ it->second->process(*_is, line_num);
3465
+ }
3466
+ readLine();
3467
+ skipSection();
3468
+ } catch (FormatError& error) {
3469
+ error.line(line_num);
3470
+ error.file(_filename);
3471
+ throw;
3472
+ }
3473
+ }
3474
+ for (Sections::iterator it = _sections.begin();
3475
+ it != _sections.end(); ++it) {
3476
+ if (extra_sections.find(it->first) == extra_sections.end()) {
3477
+ std::ostringstream os;
3478
+ os << "Cannot find section: " << it->first;
3479
+ throw FormatError(os.str());
3480
+ }
3481
+ }
3482
+ }
3483
+
3484
+ /// @}
3485
+
3486
+ };
3487
+
3488
+ /// \ingroup lemon_io
3489
+ ///
3490
+ /// \brief Return a \ref SectionReader class
3491
+ ///
3492
+ /// This function just returns a \ref SectionReader class.
3493
+ ///
3494
+ /// Please see SectionReader documentation about the custom section
3495
+ /// input.
3496
+ ///
3497
+ /// \relates SectionReader
3498
+ /// \sa sectionReader(const std::string& fn)
3499
+ /// \sa sectionReader(const char *fn)
3500
+ inline SectionReader sectionReader(std::istream& is) {
3501
+ SectionReader tmp(is);
3502
+ return tmp;
3503
+ }
3504
+
3505
+ /// \brief Return a \ref SectionReader class
3506
+ ///
3507
+ /// This function just returns a \ref SectionReader class.
3508
+ /// \relates SectionReader
3509
+ /// \sa sectionReader(std::istream& is)
3510
+ inline SectionReader sectionReader(const std::string& fn) {
3511
+ SectionReader tmp(fn);
3512
+ return tmp;
3513
+ }
3514
+
3515
+ /// \brief Return a \ref SectionReader class
3516
+ ///
3517
+ /// This function just returns a \ref SectionReader class.
3518
+ /// \relates SectionReader
3519
+ /// \sa sectionReader(std::istream& is)
3520
+ inline SectionReader sectionReader(const char* fn) {
3521
+ SectionReader tmp(fn);
3522
+ return tmp;
3523
+ }
3524
+
3525
+ /// \ingroup lemon_io
3526
+ ///
3527
+ /// \brief Reader for the contents of the \ref lgf-format "LGF" file
3528
+ ///
3529
+ /// This class can be used to read the sections, the map names and
3530
+ /// the attributes from a file. Usually, the LEMON programs know
3531
+ /// that, which type of graph, which maps and which attributes
3532
+ /// should be read from a file, but in general tools (like glemon)
3533
+ /// the contents of an LGF file should be guessed somehow. This class
3534
+ /// reads the graph and stores the appropriate information for
3535
+ /// reading the graph.
3536
+ ///
3537
+ ///\code
3538
+ /// LgfContents contents("graph.lgf");
3539
+ /// contents.run();
3540
+ ///
3541
+ /// // Does it contain any node section and arc section?
3542
+ /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
3543
+ /// std::cerr << "Failure, cannot find graph." << std::endl;
3544
+ /// return -1;
3545
+ /// }
3546
+ /// std::cout << "The name of the default node section: "
3547
+ /// << contents.nodeSection(0) << std::endl;
3548
+ /// std::cout << "The number of the arc maps: "
3549
+ /// << contents.arcMaps(0).size() << std::endl;
3550
+ /// std::cout << "The name of second arc map: "
3551
+ /// << contents.arcMaps(0)[1] << std::endl;
3552
+ ///\endcode
3553
+ class LgfContents {
3554
+ private:
3555
+
3556
+ std::istream* _is;
3557
+ bool local_is;
3558
+
3559
+ std::vector<std::string> _node_sections;
3560
+ std::vector<std::string> _edge_sections;
3561
+ std::vector<std::string> _attribute_sections;
3562
+ std::vector<std::string> _extra_sections;
3563
+
3564
+ std::vector<bool> _arc_sections;
3565
+
3566
+ std::vector<std::vector<std::string> > _node_maps;
3567
+ std::vector<std::vector<std::string> > _edge_maps;
3568
+
3569
+ std::vector<std::vector<std::string> > _attributes;
3570
+
3571
+
3572
+ int line_num;
3573
+ std::istringstream line;
3574
+
3575
+ public:
3576
+
3577
+ /// \brief Constructor
3578
+ ///
3579
+ /// Construct an \e LGF contents reader, which reads from the given
3580
+ /// input stream.
3581
+ LgfContents(std::istream& is)
3582
+ : _is(&is), local_is(false) {}
3583
+
3584
+ /// \brief Constructor
3585
+ ///
3586
+ /// Construct an \e LGF contents reader, which reads from the given
3587
+ /// file.
3588
+ LgfContents(const std::string& fn)
3589
+ : _is(new std::ifstream(fn.c_str())), local_is(true) {
3590
+ if (!(*_is)) {
3591
+ delete _is;
3592
+ throw IoError("Cannot open file", fn);
3593
+ }
3594
+ }
3595
+
3596
+ /// \brief Constructor
3597
+ ///
3598
+ /// Construct an \e LGF contents reader, which reads from the given
3599
+ /// file.
3600
+ LgfContents(const char* fn)
3601
+ : _is(new std::ifstream(fn)), local_is(true) {
3602
+ if (!(*_is)) {
3603
+ delete _is;
3604
+ throw IoError("Cannot open file", fn);
3605
+ }
3606
+ }
3607
+
3608
+ /// \brief Destructor
3609
+ ~LgfContents() {
3610
+ if (local_is) delete _is;
3611
+ }
3612
+
3613
+ private:
3614
+
3615
+ LgfContents(const LgfContents&);
3616
+ LgfContents& operator=(const LgfContents&);
3617
+
3618
+ public:
3619
+
3620
+
3621
+ /// \name Node Sections
3622
+ /// @{
3623
+
3624
+ /// \brief Gives back the number of node sections in the file.
3625
+ ///
3626
+ /// Gives back the number of node sections in the file.
3627
+ int nodeSectionNum() const {
3628
+ return _node_sections.size();
3629
+ }
3630
+
3631
+ /// \brief Returns the node section name at the given position.
3632
+ ///
3633
+ /// Returns the node section name at the given position.
3634
+ const std::string& nodeSection(int i) const {
3635
+ return _node_sections[i];
3636
+ }
3637
+
3638
+ /// \brief Gives back the node maps for the given section.
3639
+ ///
3640
+ /// Gives back the node maps for the given section.
3641
+ const std::vector<std::string>& nodeMapNames(int i) const {
3642
+ return _node_maps[i];
3643
+ }
3644
+
3645
+ /// @}
3646
+
3647
+ /// \name Arc/Edge Sections
3648
+ /// @{
3649
+
3650
+ /// \brief Gives back the number of arc/edge sections in the file.
3651
+ ///
3652
+ /// Gives back the number of arc/edge sections in the file.
3653
+ /// \note It is synonym of \c edgeSectionNum().
3654
+ int arcSectionNum() const {
3655
+ return _edge_sections.size();
3656
+ }
3657
+
3658
+ /// \brief Returns the arc/edge section name at the given position.
3659
+ ///
3660
+ /// Returns the arc/edge section name at the given position.
3661
+ /// \note It is synonym of \c edgeSection().
3662
+ const std::string& arcSection(int i) const {
3663
+ return _edge_sections[i];
3664
+ }
3665
+
3666
+ /// \brief Gives back the arc/edge maps for the given section.
3667
+ ///
3668
+ /// Gives back the arc/edge maps for the given section.
3669
+ /// \note It is synonym of \c edgeMapNames().
3670
+ const std::vector<std::string>& arcMapNames(int i) const {
3671
+ return _edge_maps[i];
3672
+ }
3673
+
3674
+ /// @}
3675
+
3676
+ /// \name Synonyms
3677
+ /// @{
3678
+
3679
+ /// \brief Gives back the number of arc/edge sections in the file.
3680
+ ///
3681
+ /// Gives back the number of arc/edge sections in the file.
3682
+ /// \note It is synonym of \c arcSectionNum().
3683
+ int edgeSectionNum() const {
3684
+ return _edge_sections.size();
3685
+ }
3686
+
3687
+ /// \brief Returns the section name at the given position.
3688
+ ///
3689
+ /// Returns the section name at the given position.
3690
+ /// \note It is synonym of \c arcSection().
3691
+ const std::string& edgeSection(int i) const {
3692
+ return _edge_sections[i];
3693
+ }
3694
+
3695
+ /// \brief Gives back the edge maps for the given section.
3696
+ ///
3697
+ /// Gives back the edge maps for the given section.
3698
+ /// \note It is synonym of \c arcMapNames().
3699
+ const std::vector<std::string>& edgeMapNames(int i) const {
3700
+ return _edge_maps[i];
3701
+ }
3702
+
3703
+ /// @}
3704
+
3705
+ /// \name Attribute Sections
3706
+ /// @{
3707
+
3708
+ /// \brief Gives back the number of attribute sections in the file.
3709
+ ///
3710
+ /// Gives back the number of attribute sections in the file.
3711
+ int attributeSectionNum() const {
3712
+ return _attribute_sections.size();
3713
+ }
3714
+
3715
+ /// \brief Returns the attribute section name at the given position.
3716
+ ///
3717
+ /// Returns the attribute section name at the given position.
3718
+ const std::string& attributeSectionNames(int i) const {
3719
+ return _attribute_sections[i];
3720
+ }
3721
+
3722
+ /// \brief Gives back the attributes for the given section.
3723
+ ///
3724
+ /// Gives back the attributes for the given section.
3725
+ const std::vector<std::string>& attributes(int i) const {
3726
+ return _attributes[i];
3727
+ }
3728
+
3729
+ /// @}
3730
+
3731
+ /// \name Extra Sections
3732
+ /// @{
3733
+
3734
+ /// \brief Gives back the number of extra sections in the file.
3735
+ ///
3736
+ /// Gives back the number of extra sections in the file.
3737
+ int extraSectionNum() const {
3738
+ return _extra_sections.size();
3739
+ }
3740
+
3741
+ /// \brief Returns the extra section type at the given position.
3742
+ ///
3743
+ /// Returns the section type at the given position.
3744
+ const std::string& extraSection(int i) const {
3745
+ return _extra_sections[i];
3746
+ }
3747
+
3748
+ /// @}
3749
+
3750
+ private:
3751
+
3752
+ bool readLine() {
3753
+ std::string str;
3754
+ while(++line_num, std::getline(*_is, str)) {
3755
+ line.clear(); line.str(str);
3756
+ char c;
3757
+ if (line >> std::ws >> c && c != '#') {
3758
+ line.putback(c);
3759
+ return true;
3760
+ }
3761
+ }
3762
+ return false;
3763
+ }
3764
+
3765
+ bool readSuccess() {
3766
+ return static_cast<bool>(*_is);
3767
+ }
3768
+
3769
+ void skipSection() {
3770
+ char c;
3771
+ while (readSuccess() && line >> c && c != '@') {
3772
+ readLine();
3773
+ }
3774
+ if (readSuccess()) {
3775
+ line.putback(c);
3776
+ }
3777
+ }
3778
+
3779
+ void readMaps(std::vector<std::string>& maps) {
3780
+ char c;
3781
+ if (!readLine() || !(line >> c) || c == '@') {
3782
+ if (readSuccess() && line) line.putback(c);
3783
+ return;
3784
+ }
3785
+ line.putback(c);
3786
+ std::string map;
3787
+ while (_reader_bits::readToken(line, map)) {
3788
+ maps.push_back(map);
3789
+ }
3790
+ }
3791
+
3792
+ void readAttributes(std::vector<std::string>& attrs) {
3793
+ readLine();
3794
+ char c;
3795
+ while (readSuccess() && line >> c && c != '@') {
3796
+ line.putback(c);
3797
+ std::string attr;
3798
+ _reader_bits::readToken(line, attr);
3799
+ attrs.push_back(attr);
3800
+ readLine();
3801
+ }
3802
+ line.putback(c);
3803
+ }
3804
+
3805
+ public:
3806
+
3807
+ /// \name Execution of the Contents Reader
3808
+ /// @{
3809
+
3810
+ /// \brief Starts the reading
3811
+ ///
3812
+ /// This function starts the reading.
3813
+ void run() {
3814
+
3815
+ readLine();
3816
+ skipSection();
3817
+
3818
+ while (readSuccess()) {
3819
+
3820
+ char c;
3821
+ line >> c;
3822
+
3823
+ std::string section, caption;
3824
+ _reader_bits::readToken(line, section);
3825
+ _reader_bits::readToken(line, caption);
3826
+
3827
+ if (section == "nodes") {
3828
+ _node_sections.push_back(caption);
3829
+ _node_maps.push_back(std::vector<std::string>());
3830
+ readMaps(_node_maps.back());
3831
+ readLine(); skipSection();
3832
+ } else if (section == "arcs" || section == "edges") {
3833
+ _edge_sections.push_back(caption);
3834
+ _arc_sections.push_back(section == "arcs");
3835
+ _edge_maps.push_back(std::vector<std::string>());
3836
+ readMaps(_edge_maps.back());
3837
+ readLine(); skipSection();
3838
+ } else if (section == "attributes") {
3839
+ _attribute_sections.push_back(caption);
3840
+ _attributes.push_back(std::vector<std::string>());
3841
+ readAttributes(_attributes.back());
3842
+ } else {
3843
+ _extra_sections.push_back(section);
3844
+ readLine(); skipSection();
3845
+ }
3846
+ }
3847
+ }
3848
+
3849
+ /// @}
3850
+
3851
+ };
3852
+ }
3853
+
3854
+ #endif