1 | # HG changeset patch |
---|
2 | # User Balazs Dezso <deba@inf.elte.hu> |
---|
3 | # Date 1207815600 -7200 |
---|
4 | # Node ID 988226bc5e6c092db643ebcb020e0a9e38f08dd0 |
---|
5 | # Parent b6bede534255e492871c601771442b65e12f7319 |
---|
6 | Redesign lgf related tools |
---|
7 | |
---|
8 | diff -r b6bede534255 -r 988226bc5e6c demo/Makefile.am |
---|
9 | --- a/demo/Makefile.am Thu Apr 03 13:00:18 2008 +0100 |
---|
10 | +++ b/demo/Makefile.am Thu Apr 10 10:20:00 2008 +0200 |
---|
11 | @@ -4,9 +4,11 @@ if WANT_DEMO |
---|
12 | if WANT_DEMO |
---|
13 | |
---|
14 | noinst_PROGRAMS += \ |
---|
15 | - demo/arg_parser_demo |
---|
16 | + demo/arg_parser_demo \ |
---|
17 | + demo/lgf_demo |
---|
18 | |
---|
19 | endif WANT_DEMO |
---|
20 | |
---|
21 | demo_arg_parser_demo_SOURCES = demo/arg_parser_demo.cc |
---|
22 | +demo_lgf_demo_SOURCES = demo/lgf_demo.cc |
---|
23 | |
---|
24 | diff -r b6bede534255 -r 988226bc5e6c demo/lgf_demo.cc |
---|
25 | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
---|
26 | +++ b/demo/lgf_demo.cc Thu Apr 10 10:20:00 2008 +0200 |
---|
27 | @@ -0,0 +1,125 @@ |
---|
28 | +/* -*- C++ -*- |
---|
29 | + * |
---|
30 | + * This file is a part of LEMON, a generic C++ optimization library |
---|
31 | + * |
---|
32 | + * Copyright (C) 2003-2008 |
---|
33 | + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
---|
34 | + * (Egervary Research Group on Combinatorial Optimization, EGRES). |
---|
35 | + * |
---|
36 | + * Permission to use, modify and distribute this software is granted |
---|
37 | + * provided that this copyright notice appears in all copies. For |
---|
38 | + * precise terms see the accompanying LICENSE file. |
---|
39 | + * |
---|
40 | + * This software is provided "AS IS" with no warranty of any kind, |
---|
41 | + * express or implied, and with no claim as to its suitability for any |
---|
42 | + * purpose. |
---|
43 | + * |
---|
44 | + */ |
---|
45 | + |
---|
46 | +///\ingroup demos |
---|
47 | +///\file |
---|
48 | +///\brief Demonstrating graph input and output |
---|
49 | +/// |
---|
50 | +/// This simple demo program gives an example of how to read and write |
---|
51 | +/// a graph and additional maps (on the nodes or the edges) from/to a |
---|
52 | +/// stream. |
---|
53 | +/// |
---|
54 | +/// \include reader_writer_demo.cc |
---|
55 | + |
---|
56 | +#include <iostream> |
---|
57 | +#include <lemon/smart_graph.h> |
---|
58 | +#include <lemon/lgf_reader.h> |
---|
59 | +#include <lemon/lgf_writer.h> |
---|
60 | +#include <lemon/random.h> |
---|
61 | + |
---|
62 | + |
---|
63 | +using namespace lemon; |
---|
64 | + |
---|
65 | +int main(int argc, const char *argv[]) { |
---|
66 | + SmartDigraph digraph; |
---|
67 | + |
---|
68 | + std::stringstream ss; |
---|
69 | + |
---|
70 | + try { |
---|
71 | + |
---|
72 | + typedef SmartDigraph Digraph; |
---|
73 | + typedef Digraph::Node Node; |
---|
74 | + typedef Digraph::Arc Arc; |
---|
75 | + typedef Digraph::ArcIt ArcIt; |
---|
76 | + |
---|
77 | + typedef Digraph::ArcMap<int> CapacityMap; |
---|
78 | + typedef Digraph::ArcMap<std::string> NameMap; |
---|
79 | + |
---|
80 | + const int n = argc > 1 ? std::atoi(argv[1]) : 20; |
---|
81 | + const int e = argc > 2 ? std::atoi(argv[2]) : static_cast<int>(n * log(n)); |
---|
82 | + const int m = argc > 3 ? std::atoi(argv[3]) : 100; |
---|
83 | + |
---|
84 | + Digraph digraph; |
---|
85 | + CapacityMap capacity(digraph); |
---|
86 | + NameMap name(digraph); |
---|
87 | + |
---|
88 | + std::vector<Node> nodes; |
---|
89 | + |
---|
90 | + for (int i = 0; i < n; ++i) { |
---|
91 | + nodes.push_back(digraph.addNode()); |
---|
92 | + } |
---|
93 | + for (int i = 0; i < e; ++i) { |
---|
94 | + int s = rnd[n]; |
---|
95 | + int t = rnd[n]; |
---|
96 | + int c = rnd[m]; |
---|
97 | + Arc arc = digraph.addArc(nodes[s], nodes[t]); |
---|
98 | + capacity[arc] = c; |
---|
99 | + std::ostringstream os; |
---|
100 | + os << "arc \t" << i << std::endl; |
---|
101 | + name[arc] = os.str(); |
---|
102 | + } |
---|
103 | + |
---|
104 | + |
---|
105 | + DigraphWriter<Digraph>(ss, digraph). |
---|
106 | + arcMap("capacity", capacity). |
---|
107 | + arcMap("name", name). |
---|
108 | + node("source", nodes[0]). |
---|
109 | + node("target", nodes[1]). |
---|
110 | + run(); |
---|
111 | + |
---|
112 | + } catch (DataFormatError& error) { |
---|
113 | + std::cerr << error.what() << std::endl; |
---|
114 | + } |
---|
115 | + |
---|
116 | + try { |
---|
117 | + |
---|
118 | + typedef SmartDigraph Digraph; |
---|
119 | + typedef Digraph::Node Node; |
---|
120 | + typedef Digraph::Arc Arc; |
---|
121 | + typedef Digraph::ArcIt ArcIt; |
---|
122 | + |
---|
123 | + typedef Digraph::ArcMap<int> CapacityMap; |
---|
124 | + typedef Digraph::ArcMap<std::string> NameMap; |
---|
125 | + |
---|
126 | + Digraph digraph; |
---|
127 | + CapacityMap capacity(digraph); |
---|
128 | + NameMap name(digraph); |
---|
129 | + |
---|
130 | + Node s, t; |
---|
131 | + |
---|
132 | + DigraphReader<Digraph>(ss, digraph). |
---|
133 | + arcMap("capacity", capacity). |
---|
134 | + arcMap("name", name). |
---|
135 | + node("source", s). |
---|
136 | + node("target", t). |
---|
137 | + run(); |
---|
138 | + |
---|
139 | + DigraphWriter<Digraph>(std::cout, digraph). |
---|
140 | + arcMap("capacity", capacity). |
---|
141 | + arcMap("name", name). |
---|
142 | + node("source", s). |
---|
143 | + node("target", t). |
---|
144 | + run(); |
---|
145 | + |
---|
146 | + } catch (DataFormatError& error) { |
---|
147 | + std::cerr << error.what() << std::endl; |
---|
148 | + } |
---|
149 | + |
---|
150 | + |
---|
151 | + return 0; |
---|
152 | +} |
---|
153 | diff -r b6bede534255 -r 988226bc5e6c lemon/Makefile.am |
---|
154 | --- a/lemon/Makefile.am Thu Apr 03 13:00:18 2008 +0100 |
---|
155 | +++ b/lemon/Makefile.am Thu Apr 10 10:20:00 2008 +0200 |
---|
156 | @@ -26,6 +26,7 @@ lemon_HEADERS += \ |
---|
157 | lemon/error.h \ |
---|
158 | lemon/graph_utils.h \ |
---|
159 | lemon/kruskal.h \ |
---|
160 | + lemon/lgf_reader.h \ |
---|
161 | lemon/list_graph.h \ |
---|
162 | lemon/maps.h \ |
---|
163 | lemon/math.h \ |
---|
164 | diff -r b6bede534255 -r 988226bc5e6c lemon/lgf_reader.h |
---|
165 | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
---|
166 | +++ b/lemon/lgf_reader.h Thu Apr 10 10:20:00 2008 +0200 |
---|
167 | @@ -0,0 +1,866 @@ |
---|
168 | +/* -*- C++ -*- |
---|
169 | + * |
---|
170 | + * This file is a part of LEMON, a generic C++ optimization library |
---|
171 | + * |
---|
172 | + * Copyright (C) 2003-2008 |
---|
173 | + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
---|
174 | + * (Egervary Research Group on Combinatorial Optimization, EGRES). |
---|
175 | + * |
---|
176 | + * Permission to use, modify and distribute this software is granted |
---|
177 | + * provided that this copyright notice appears in all copies. For |
---|
178 | + * precise terms see the accompanying LICENSE file. |
---|
179 | + * |
---|
180 | + * This software is provided "AS IS" with no warranty of any kind, |
---|
181 | + * express or implied, and with no claim as to its suitability for any |
---|
182 | + * purpose. |
---|
183 | + * |
---|
184 | + */ |
---|
185 | + |
---|
186 | +///\ingroup lemon_io |
---|
187 | +///\file |
---|
188 | +///\brief Lemon Graph Format reader. |
---|
189 | + |
---|
190 | + |
---|
191 | +#ifndef LEMON_LGF_READER_H |
---|
192 | +#define LEMON_LGF_READER_H |
---|
193 | + |
---|
194 | +#include <iostream> |
---|
195 | +#include <fstream> |
---|
196 | +#include <sstream> |
---|
197 | + |
---|
198 | +#include <map> |
---|
199 | +#include <typeinfo> |
---|
200 | + |
---|
201 | +#include <lemon/assert.h> |
---|
202 | +#include <lemon/graph_utils.h> |
---|
203 | + |
---|
204 | +namespace lemon { |
---|
205 | + |
---|
206 | + namespace _reader_bits { |
---|
207 | + |
---|
208 | + template <typename Value> |
---|
209 | + struct DefaultConverter { |
---|
210 | + Value operator()(const std::string& str) { |
---|
211 | + std::istringstream is(str); |
---|
212 | + Value value; |
---|
213 | + is >> value; |
---|
214 | + |
---|
215 | + char c; |
---|
216 | + if (is >> std::ws >> c) { |
---|
217 | + throw DataFormatError("Remaining characters in token"); |
---|
218 | + } |
---|
219 | + return value; |
---|
220 | + } |
---|
221 | + }; |
---|
222 | + |
---|
223 | + template <> |
---|
224 | + struct DefaultConverter<std::string> { |
---|
225 | + std::string operator()(const std::string& str) { |
---|
226 | + return str; |
---|
227 | + } |
---|
228 | + }; |
---|
229 | + |
---|
230 | + template <typename _Item> |
---|
231 | + class MapStorageBase { |
---|
232 | + public: |
---|
233 | + typedef _Item Item; |
---|
234 | + |
---|
235 | + private: |
---|
236 | + bool _touched; |
---|
237 | + |
---|
238 | + public: |
---|
239 | + MapStorageBase() : _touched(false) {} |
---|
240 | + virtual ~MapStorageBase() {} |
---|
241 | + |
---|
242 | + void touch(bool value = true) { _touched = value; } |
---|
243 | + bool touched() const { return _touched; } |
---|
244 | + |
---|
245 | + virtual void set(const Item& item, const std::string& value) = 0; |
---|
246 | + |
---|
247 | + }; |
---|
248 | + |
---|
249 | + template <typename _Item, typename _Map, |
---|
250 | + typename _Converter = DefaultConverter<typename _Map::Value> > |
---|
251 | + class MapStorage : public MapStorageBase<_Item> { |
---|
252 | + public: |
---|
253 | + typedef _Map Map; |
---|
254 | + typedef _Converter Converter; |
---|
255 | + typedef _Item Item; |
---|
256 | + |
---|
257 | + private: |
---|
258 | + Map& _map; |
---|
259 | + Converter _converter; |
---|
260 | + |
---|
261 | + public: |
---|
262 | + MapStorage(Map& map, const Converter& converter = Converter()) |
---|
263 | + : _map(map), _converter(converter) {} |
---|
264 | + virtual ~MapStorage() {} |
---|
265 | + |
---|
266 | + virtual void set(const Item& item ,const std::string& value) { |
---|
267 | + _map.set(item, _converter(value)); |
---|
268 | + } |
---|
269 | + }; |
---|
270 | + |
---|
271 | + class ValueStorageBase { |
---|
272 | + private: |
---|
273 | + bool _touched; |
---|
274 | + |
---|
275 | + public: |
---|
276 | + ValueStorageBase() : _touched(false) {} |
---|
277 | + virtual ~ValueStorageBase() {} |
---|
278 | + |
---|
279 | + void touch() { _touched = true; } |
---|
280 | + bool touched() const { return _touched; } |
---|
281 | + |
---|
282 | + virtual void set(const std::string&) = 0; |
---|
283 | + }; |
---|
284 | + |
---|
285 | + template <typename _Value, typename _Converter = DefaultConverter<_Value> > |
---|
286 | + class ValueStorage : public ValueStorageBase { |
---|
287 | + public: |
---|
288 | + typedef _Value Value; |
---|
289 | + typedef _Converter Converter; |
---|
290 | + |
---|
291 | + private: |
---|
292 | + Value& _value; |
---|
293 | + Converter _converter; |
---|
294 | + |
---|
295 | + public: |
---|
296 | + ValueStorage(Value& value, const Converter& converter = Converter()) |
---|
297 | + : _value(value), _converter(converter) {} |
---|
298 | + |
---|
299 | + virtual void set(const std::string& value) { |
---|
300 | + _value = _converter(value); |
---|
301 | + } |
---|
302 | + }; |
---|
303 | + |
---|
304 | + |
---|
305 | + class FilterStreamBuf : public std::streambuf { |
---|
306 | + public: |
---|
307 | + |
---|
308 | + typedef std::streambuf Parent; |
---|
309 | + typedef Parent::char_type char_type; |
---|
310 | + FilterStreamBuf(std::istream& is, int& num) |
---|
311 | + : _is(is), _base(0), _eptr(0), |
---|
312 | + _num(num), skip_state(after_endl) {} |
---|
313 | + |
---|
314 | + protected: |
---|
315 | + |
---|
316 | + enum skip_state_type { |
---|
317 | + no_skip, |
---|
318 | + after_endl, |
---|
319 | + comment_line |
---|
320 | + }; |
---|
321 | + |
---|
322 | + char_type small_buf[1]; |
---|
323 | + |
---|
324 | + |
---|
325 | + std::istream& _is; |
---|
326 | + |
---|
327 | + char_type* _base; |
---|
328 | + char_type* _eptr; |
---|
329 | + |
---|
330 | + int& _num; |
---|
331 | + |
---|
332 | + skip_state_type skip_state; |
---|
333 | + |
---|
334 | + |
---|
335 | + char_type* base() { return _base; } |
---|
336 | + char_type* eptr() { return _eptr; } |
---|
337 | + int_type blen() { return _eptr - _base; } |
---|
338 | + |
---|
339 | + void setb(char_type* buf, int_type len) { |
---|
340 | + _base = buf; |
---|
341 | + _eptr = buf + len; |
---|
342 | + } |
---|
343 | + |
---|
344 | + virtual std::streambuf* setbuf(char *buf, std::streamsize len) { |
---|
345 | + if (base()) return 0; |
---|
346 | + if (buf != 0 && len >= int(sizeof(small_buf))) { |
---|
347 | + setb(buf, len); |
---|
348 | + } else { |
---|
349 | + setb(small_buf, sizeof(small_buf)); |
---|
350 | + } |
---|
351 | + setg(0, 0, 0); |
---|
352 | + return this; |
---|
353 | + } |
---|
354 | + |
---|
355 | + bool put_char(char c) { |
---|
356 | + switch (skip_state) { |
---|
357 | + case no_skip: |
---|
358 | + switch (c) { |
---|
359 | + case '\n': |
---|
360 | + skip_state = after_endl; |
---|
361 | + return true; |
---|
362 | + default: |
---|
363 | + return true; |
---|
364 | + } |
---|
365 | + case after_endl: |
---|
366 | + switch (c) { |
---|
367 | + case '@': |
---|
368 | + return false; |
---|
369 | + case '\n': |
---|
370 | + return false; |
---|
371 | + case '#': |
---|
372 | + skip_state = comment_line; |
---|
373 | + return false; |
---|
374 | + default: |
---|
375 | + if (!isspace(c)) { |
---|
376 | + skip_state = no_skip; |
---|
377 | + return true; |
---|
378 | + } else { |
---|
379 | + return false; |
---|
380 | + } |
---|
381 | + } |
---|
382 | + break; |
---|
383 | + case comment_line: |
---|
384 | + switch (c) { |
---|
385 | + case '\n': |
---|
386 | + skip_state = after_endl; |
---|
387 | + return false; |
---|
388 | + default: |
---|
389 | + return false; |
---|
390 | + } |
---|
391 | + } |
---|
392 | + return false; |
---|
393 | + } |
---|
394 | + |
---|
395 | + virtual int_type underflow() { |
---|
396 | + char c; |
---|
397 | + if ((c = _is.peek()) != EOF) { |
---|
398 | + if (c == '@') { |
---|
399 | + return EOF; |
---|
400 | + } |
---|
401 | + } else { |
---|
402 | + return EOF; |
---|
403 | + } |
---|
404 | + char_type *ptr; |
---|
405 | + for (ptr = base(); ptr != eptr(); ++ptr) { |
---|
406 | + if ((c = _is.get()) != EOF) { |
---|
407 | + if (c == '\n') ++_num; |
---|
408 | + if (put_char(c)) { |
---|
409 | + *ptr = c; |
---|
410 | + } else { |
---|
411 | + if (skip_state == after_endl && c == '@') { |
---|
412 | + _is.putback(c); |
---|
413 | + break; |
---|
414 | + } |
---|
415 | + --ptr; |
---|
416 | + } |
---|
417 | + } else { |
---|
418 | + break; |
---|
419 | + } |
---|
420 | + } |
---|
421 | + setg(base(), base(), ptr); |
---|
422 | + return *base(); |
---|
423 | + } |
---|
424 | + |
---|
425 | + virtual int_type sync() { |
---|
426 | + return EOF; |
---|
427 | + } |
---|
428 | + |
---|
429 | + public: |
---|
430 | + |
---|
431 | + int line_num() const { |
---|
432 | + int r = _num; |
---|
433 | + for (char_type* p = gptr(); p != egptr(); ++p) { |
---|
434 | + if (*p == '\n') --r; |
---|
435 | + } |
---|
436 | + return r; |
---|
437 | + } |
---|
438 | + |
---|
439 | + }; |
---|
440 | + |
---|
441 | + template <typename Value> |
---|
442 | + struct MapLookUpConverter { |
---|
443 | + const std::map<std::string, Value>& _map; |
---|
444 | + |
---|
445 | + MapLookUpConverter(const std::map<std::string, Value>& map) |
---|
446 | + : _map(map) {} |
---|
447 | + |
---|
448 | + Value operator()(const std::string& str) { |
---|
449 | + typename std::map<std::string, Value>::const_iterator it = |
---|
450 | + _map.find(str); |
---|
451 | + |
---|
452 | + if (it == _map.end()) { |
---|
453 | + std::ostringstream msg; |
---|
454 | + msg << "Item not found: " << str; |
---|
455 | + throw DataFormatError(msg.str().c_str()); |
---|
456 | + } |
---|
457 | + return it->second; |
---|
458 | + } |
---|
459 | + }; |
---|
460 | + |
---|
461 | + bool isWhiteSpace(char c) { |
---|
462 | + return c == ' ' || c == '\t' || c == '\v' || |
---|
463 | + c == '\n' || c == '\r' || c == '\f'; |
---|
464 | + } |
---|
465 | + |
---|
466 | + bool isOct(char c) { |
---|
467 | + return '0' <= c && c <='7'; |
---|
468 | + } |
---|
469 | + |
---|
470 | + int valueOct(char c) { |
---|
471 | + LEMON_ASSERT(isOct(c), "The character is not octal."); |
---|
472 | + return c - '0'; |
---|
473 | + } |
---|
474 | + |
---|
475 | + bool isHex(char c) { |
---|
476 | + return ('0' <= c && c <= '9') || |
---|
477 | + ('a' <= c && c <= 'z') || |
---|
478 | + ('A' <= c && c <= 'Z'); |
---|
479 | + } |
---|
480 | + |
---|
481 | + int valueHex(char c) { |
---|
482 | + LEMON_ASSERT(isHex(c), "The character is not hexadecimal."); |
---|
483 | + if ('0' <= c && c <= '9') return c - '0'; |
---|
484 | + if ('a' <= c && c <= 'z') return c - 'a' + 10; |
---|
485 | + return c - 'A' + 10; |
---|
486 | + } |
---|
487 | + |
---|
488 | + char readEscape(std::istream& is) { |
---|
489 | + char c; |
---|
490 | + if (!is.get(c)) |
---|
491 | + throw DataFormatError("Escape format error"); |
---|
492 | + |
---|
493 | + switch (c) { |
---|
494 | + case '\\': |
---|
495 | + return '\\'; |
---|
496 | + case '\"': |
---|
497 | + return '\"'; |
---|
498 | + case '\'': |
---|
499 | + return '\''; |
---|
500 | + case '\?': |
---|
501 | + return '\?'; |
---|
502 | + case 'a': |
---|
503 | + return '\a'; |
---|
504 | + case 'b': |
---|
505 | + return '\b'; |
---|
506 | + case 'f': |
---|
507 | + return '\f'; |
---|
508 | + case 'n': |
---|
509 | + return '\n'; |
---|
510 | + case 'r': |
---|
511 | + return '\r'; |
---|
512 | + case 't': |
---|
513 | + return '\t'; |
---|
514 | + case 'v': |
---|
515 | + return '\v'; |
---|
516 | + case 'x': |
---|
517 | + { |
---|
518 | + int code; |
---|
519 | + if (!is.get(c) || !isHex(c)) |
---|
520 | + throw DataFormatError("Escape format error"); |
---|
521 | + else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c); |
---|
522 | + else code = code * 16 + valueHex(c); |
---|
523 | + return code; |
---|
524 | + } |
---|
525 | + default: |
---|
526 | + { |
---|
527 | + int code; |
---|
528 | + if (!isOct(c)) |
---|
529 | + throw DataFormatError("Escape format error"); |
---|
530 | + else if (code = valueOct(c), !is.get(c) || !isOct(c)) |
---|
531 | + is.putback(c); |
---|
532 | + else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) |
---|
533 | + is.putback(c); |
---|
534 | + else code = code * 8 + valueOct(c); |
---|
535 | + return code; |
---|
536 | + } |
---|
537 | + } |
---|
538 | + } |
---|
539 | + |
---|
540 | + |
---|
541 | + std::istream& readToken(std::istream& is, std::string& str) { |
---|
542 | + std::ostringstream os; |
---|
543 | + |
---|
544 | + char c; |
---|
545 | + is >> std::ws; |
---|
546 | + |
---|
547 | + if (!is.get(c)) |
---|
548 | + throw DataFormatError("Token not found"); |
---|
549 | + |
---|
550 | + if (c == '\"') { |
---|
551 | + while (is.get(c) && c != '\"') { |
---|
552 | + if (c == '\\') |
---|
553 | + c = readEscape(is); |
---|
554 | + os << c; |
---|
555 | + } |
---|
556 | + if (!is) |
---|
557 | + throw DataFormatError("Quoted format error"); |
---|
558 | + } else { |
---|
559 | + is.putback(c); |
---|
560 | + while (is.get(c) && !isWhiteSpace(c)) { |
---|
561 | + if (c == '\\') |
---|
562 | + c = readEscape(is); |
---|
563 | + os << c; |
---|
564 | + } |
---|
565 | + if (!is) { |
---|
566 | + is.setstate(std::ios_base::goodbit); |
---|
567 | + } else { |
---|
568 | + is.putback(c); |
---|
569 | + } |
---|
570 | + } |
---|
571 | + str = os.str(); |
---|
572 | + return is; |
---|
573 | + } |
---|
574 | + |
---|
575 | + } |
---|
576 | + |
---|
577 | + /// \e |
---|
578 | + template <typename _Digraph> |
---|
579 | + class DigraphReader { |
---|
580 | + public: |
---|
581 | + |
---|
582 | + typedef _Digraph Digraph; |
---|
583 | + GRAPH_TYPEDEFS(typename Digraph); |
---|
584 | + |
---|
585 | + private: |
---|
586 | + |
---|
587 | + |
---|
588 | + std::istream* _is; |
---|
589 | + bool local_is; |
---|
590 | + |
---|
591 | + Digraph& _digraph; |
---|
592 | + |
---|
593 | + std::string _node_set_caption; |
---|
594 | + std::string _arc_set_caption; |
---|
595 | + std::string _attributes_caption; |
---|
596 | + |
---|
597 | + typedef std::map<std::string, Node> NodeIndex; |
---|
598 | + NodeIndex _node_index; |
---|
599 | + typedef std::map<std::string, Arc> ArcIndex; |
---|
600 | + ArcIndex _arc_index; |
---|
601 | + |
---|
602 | + typedef std::multimap<std::string, _reader_bits::MapStorageBase<Node>* > |
---|
603 | + NodeMaps; |
---|
604 | + NodeMaps _node_maps; |
---|
605 | + |
---|
606 | + typedef std::multimap<std::string, _reader_bits::MapStorageBase<Arc>* > |
---|
607 | + ArcMaps; |
---|
608 | + ArcMaps _arc_maps; |
---|
609 | + |
---|
610 | + typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> |
---|
611 | + Attributes; |
---|
612 | + Attributes _attributes; |
---|
613 | + |
---|
614 | + public: |
---|
615 | + |
---|
616 | + /// \e |
---|
617 | + DigraphReader(std::istream& is, Digraph& digraph) |
---|
618 | + : _is(&is), local_is(false), _digraph(digraph) {} |
---|
619 | + |
---|
620 | + /// \e |
---|
621 | + DigraphReader(const std::string& fn, Digraph& digraph) |
---|
622 | + : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph) {} |
---|
623 | + |
---|
624 | + /// \e |
---|
625 | + DigraphReader(const char* fn, Digraph& digraph) |
---|
626 | + : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph) {} |
---|
627 | + |
---|
628 | + DigraphReader(DigraphReader& other) |
---|
629 | + : _is(other._is), local_is(other.local_is), _digraph(other._digraph) { |
---|
630 | + |
---|
631 | + other.is = 0; |
---|
632 | + other.local_is = false; |
---|
633 | + |
---|
634 | + _node_index.swap(other._node_index); |
---|
635 | + _arc_index.swap(other._arc_index); |
---|
636 | + |
---|
637 | + _node_maps.swap(other._node_maps); |
---|
638 | + _arc_maps.swap(other._arc_maps); |
---|
639 | + _attributes.swap(other._attributes); |
---|
640 | + |
---|
641 | + _node_set_caption = other._node_set_caption; |
---|
642 | + _arc_set_caption = other._arc_set_caption; |
---|
643 | + _attributes_caption = other._attributes_caption; |
---|
644 | + } |
---|
645 | + |
---|
646 | + /// \e |
---|
647 | + ~DigraphReader() { |
---|
648 | + for (typename NodeMaps::iterator it = _node_maps.begin(); |
---|
649 | + it != _node_maps.end(); ++it) { |
---|
650 | + delete it->second; |
---|
651 | + } |
---|
652 | + |
---|
653 | + for (typename ArcMaps::iterator it = _arc_maps.begin(); |
---|
654 | + it != _arc_maps.end(); ++it) { |
---|
655 | + delete it->second; |
---|
656 | + } |
---|
657 | + |
---|
658 | + for (typename Attributes::iterator it = _attributes.begin(); |
---|
659 | + it != _attributes.end(); ++it) { |
---|
660 | + delete it->second; |
---|
661 | + } |
---|
662 | + |
---|
663 | + if (local_is) { |
---|
664 | + delete _is; |
---|
665 | + } |
---|
666 | + } |
---|
667 | + |
---|
668 | + private: |
---|
669 | + |
---|
670 | + DigraphReader& operator=(const DigraphReader&); |
---|
671 | + |
---|
672 | + public: |
---|
673 | + |
---|
674 | + /// \e |
---|
675 | + template <typename Map> |
---|
676 | + DigraphReader& nodeMap(const std::string& caption, Map& map) { |
---|
677 | + _reader_bits::MapStorageBase<Node>* storage = |
---|
678 | + new _reader_bits::MapStorage<Node, Map>(map); |
---|
679 | + _node_maps.insert(std::make_pair(caption, storage)); |
---|
680 | + return *this; |
---|
681 | + } |
---|
682 | + |
---|
683 | + /// \e |
---|
684 | + template <typename Map, typename Converter> |
---|
685 | + DigraphReader& nodeMap(const std::string& caption, Map& map, |
---|
686 | + const Converter& converter = Converter()) { |
---|
687 | + _reader_bits::MapStorageBase<Node>* storage = |
---|
688 | + new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
---|
689 | + _node_maps.insert(std::make_pair(caption, storage)); |
---|
690 | + return *this; |
---|
691 | + } |
---|
692 | + |
---|
693 | + /// \e |
---|
694 | + template <typename Map> |
---|
695 | + DigraphReader& arcMap(const std::string& caption, Map& map) { |
---|
696 | + _reader_bits::MapStorageBase<Arc>* storage = |
---|
697 | + new _reader_bits::MapStorage<Arc, Map>(map); |
---|
698 | + _arc_maps.insert(std::make_pair(caption, storage)); |
---|
699 | + return *this; |
---|
700 | + } |
---|
701 | + |
---|
702 | + /// \e |
---|
703 | + template <typename Map, typename Converter> |
---|
704 | + DigraphReader& arcMap(const std::string& caption, Map& map, |
---|
705 | + const Converter& converter = Converter()) { |
---|
706 | + _reader_bits::MapStorageBase<Arc>* storage = |
---|
707 | + new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter); |
---|
708 | + _arc_maps.insert(std::make_pair(caption, storage)); |
---|
709 | + return *this; |
---|
710 | + } |
---|
711 | + |
---|
712 | + /// \e |
---|
713 | + template <typename Value> |
---|
714 | + DigraphReader& attribute(const std::string& caption, Value& value) { |
---|
715 | + _reader_bits::ValueStorageBase* storage = |
---|
716 | + new _reader_bits::ValueStorage<Value>(value); |
---|
717 | + _attributes.insert(std::make_pair(caption, storage)); |
---|
718 | + return *this; |
---|
719 | + } |
---|
720 | + |
---|
721 | + /// \e |
---|
722 | + template <typename Value, typename Converter> |
---|
723 | + DigraphReader& attribute(const std::string& caption, Value& value, |
---|
724 | + const Converter& converter = Converter()) { |
---|
725 | + _reader_bits::ValueStorageBase* storage = |
---|
726 | + new _reader_bits::ValueStorage<Value, Converter>(value, converter); |
---|
727 | + _attributes.insert(std::make_pair(caption, storage)); |
---|
728 | + return *this; |
---|
729 | + } |
---|
730 | + |
---|
731 | + /// \e |
---|
732 | + DigraphReader& node(const std::string& caption, Node& node) { |
---|
733 | + typedef _reader_bits::MapLookUpConverter<Node> Converter; |
---|
734 | + Converter converter(_node_index); |
---|
735 | + _reader_bits::ValueStorageBase* storage = |
---|
736 | + new _reader_bits::ValueStorage<Node, Converter>(node, converter); |
---|
737 | + _attributes.insert(std::make_pair(caption, storage)); |
---|
738 | + return *this; |
---|
739 | + } |
---|
740 | + |
---|
741 | + /// \e |
---|
742 | + DigraphReader& arc(const std::string& caption, Arc& arc) { |
---|
743 | + typedef _reader_bits::MapLookUpConverter<Arc> Converter; |
---|
744 | + Converter converter(_arc_index); |
---|
745 | + _reader_bits::ValueStorageBase* storage = |
---|
746 | + new _reader_bits::ValueStorage<Arc, Converter>(arc, converter); |
---|
747 | + _attributes.insert(std::make_pair(caption, storage)); |
---|
748 | + return *this; |
---|
749 | + } |
---|
750 | + |
---|
751 | + /// \e |
---|
752 | + DigraphReader& nodeSet(const std::string& caption) { |
---|
753 | + _node_set_caption = caption; |
---|
754 | + return *this; |
---|
755 | + } |
---|
756 | + |
---|
757 | + /// \e |
---|
758 | + DigraphReader& arcSet(const std::string& caption) { |
---|
759 | + _arc_set_caption = caption; |
---|
760 | + return *this; |
---|
761 | + } |
---|
762 | + |
---|
763 | + /// \e |
---|
764 | + DigraphReader& attributes(const std::string& caption) { |
---|
765 | + _attributes_caption = caption; |
---|
766 | + return *this; |
---|
767 | + } |
---|
768 | + |
---|
769 | + private: |
---|
770 | + |
---|
771 | + |
---|
772 | + static void skipSection(std::istream& is, int& line_num) { |
---|
773 | + enum skip_state_type { skip, after_endl }; |
---|
774 | + |
---|
775 | + skip_state_type skip_state = after_endl; |
---|
776 | + char c; |
---|
777 | + |
---|
778 | + while ((c = is.get()) != EOF) { |
---|
779 | + if (c == '\n') ++line_num; |
---|
780 | + |
---|
781 | + switch (skip_state) { |
---|
782 | + case skip: |
---|
783 | + if (c == '\n') skip_state = after_endl; |
---|
784 | + break; |
---|
785 | + case after_endl: |
---|
786 | + switch (c) { |
---|
787 | + case '@': |
---|
788 | + is.putback(c); |
---|
789 | + return; |
---|
790 | + case '\n': |
---|
791 | + continue; |
---|
792 | + default: |
---|
793 | + if (!isspace(c)) { |
---|
794 | + skip_state = skip; |
---|
795 | + } |
---|
796 | + break; |
---|
797 | + } |
---|
798 | + } |
---|
799 | + } |
---|
800 | + } |
---|
801 | + |
---|
802 | + void readNodeSet(std::istream& is) { |
---|
803 | + |
---|
804 | + std::vector<std::string> maps; |
---|
805 | + std::string line; |
---|
806 | + |
---|
807 | + { |
---|
808 | + std::getline(is, line); |
---|
809 | + std::istringstream ls(line); |
---|
810 | + |
---|
811 | + std::string map; |
---|
812 | + while (ls >> map) { |
---|
813 | + maps.push_back(map); |
---|
814 | + |
---|
815 | + typename NodeMaps::iterator it = _node_maps.lower_bound(map); |
---|
816 | + while (it != _node_maps.end() && it->first == map) { |
---|
817 | + it->second->touch(); |
---|
818 | + ++it; |
---|
819 | + } |
---|
820 | + } |
---|
821 | + |
---|
822 | + for (typename NodeMaps::iterator it = _node_maps.begin(); |
---|
823 | + it != _node_maps.end(); ++it) { |
---|
824 | + if (!it->second->touched()) { |
---|
825 | + ErrorMessage msg; |
---|
826 | + msg << "Map not found in file: " << it->first; |
---|
827 | + throw IoParameterError(msg.message()); |
---|
828 | + } |
---|
829 | + } |
---|
830 | + } |
---|
831 | + |
---|
832 | + while (getline(is, line)) { |
---|
833 | + Node n = _digraph.addNode(); |
---|
834 | + |
---|
835 | + std::istringstream ls(line); |
---|
836 | + for (int i = 0; i < static_cast<int>(maps.size()); ++i) { |
---|
837 | + std::string token; |
---|
838 | + _reader_bits::readToken(ls, token); |
---|
839 | + |
---|
840 | + typename NodeMaps::iterator it = _node_maps.lower_bound(maps[i]); |
---|
841 | + while (it != _node_maps.end() && it->first == maps[i]) { |
---|
842 | + it->second->set(n, token); |
---|
843 | + ++it; |
---|
844 | + } |
---|
845 | + |
---|
846 | + if (maps[i] == "label") { |
---|
847 | + _node_index[token] = n; |
---|
848 | + } |
---|
849 | + } |
---|
850 | + } |
---|
851 | + } |
---|
852 | + |
---|
853 | + void readArcSet(std::istream& is) { |
---|
854 | + |
---|
855 | + std::vector<std::string> maps; |
---|
856 | + std::string line; |
---|
857 | + |
---|
858 | + { |
---|
859 | + |
---|
860 | + std::getline(is, line); |
---|
861 | + std::istringstream ls(line); |
---|
862 | + |
---|
863 | + std::string map; |
---|
864 | + while (ls >> map) { |
---|
865 | + maps.push_back(map); |
---|
866 | + |
---|
867 | + typename ArcMaps::iterator it = _arc_maps.lower_bound(map); |
---|
868 | + while (it != _arc_maps.end() && it->first == map) { |
---|
869 | + it->second->touch(); |
---|
870 | + ++it; |
---|
871 | + } |
---|
872 | + } |
---|
873 | + |
---|
874 | + for (typename ArcMaps::iterator it = _arc_maps.begin(); |
---|
875 | + it != _arc_maps.end(); ++it) { |
---|
876 | + if (!it->second->touched()) { |
---|
877 | + ErrorMessage msg; |
---|
878 | + msg << "Map not found in file: " << it->first; |
---|
879 | + throw IoParameterError(msg.message()); |
---|
880 | + } |
---|
881 | + } |
---|
882 | + } |
---|
883 | + |
---|
884 | + while (getline(is, line)) { |
---|
885 | + std::istringstream ls(line); |
---|
886 | + |
---|
887 | + Node s, t; |
---|
888 | + { |
---|
889 | + std::string token; |
---|
890 | + typename NodeIndex::iterator it; |
---|
891 | + |
---|
892 | + _reader_bits::readToken(ls, token); |
---|
893 | + it = _node_index.find(token); |
---|
894 | + if (it == _node_index.end()) { |
---|
895 | + std::ostringstream msg; |
---|
896 | + msg << "Item not found: " << token; |
---|
897 | + throw DataFormatError(msg.str().c_str()); |
---|
898 | + } |
---|
899 | + s = it->second; |
---|
900 | + |
---|
901 | + _reader_bits::readToken(ls, token); |
---|
902 | + it = _node_index.find(token); |
---|
903 | + if (it == _node_index.end()) { |
---|
904 | + std::ostringstream msg; |
---|
905 | + msg << "Item not found: " << token; |
---|
906 | + throw DataFormatError(msg.str().c_str()); |
---|
907 | + } |
---|
908 | + t = it->second; |
---|
909 | + } |
---|
910 | + |
---|
911 | + Arc a = _digraph.addArc(s, t); |
---|
912 | + |
---|
913 | + for (int i = 0; i < static_cast<int>(maps.size()); ++i) { |
---|
914 | + std::string token; |
---|
915 | + _reader_bits::readToken(ls, token); |
---|
916 | + |
---|
917 | + typename ArcMaps::iterator it = _arc_maps.lower_bound(maps[i]); |
---|
918 | + while (it != _arc_maps.end() && it->first == maps[i]) { |
---|
919 | + it->second->set(a, token); |
---|
920 | + ++it; |
---|
921 | + } |
---|
922 | + |
---|
923 | + if (maps[i] == "label") { |
---|
924 | + _arc_index[token] = a; |
---|
925 | + } |
---|
926 | + } |
---|
927 | + } |
---|
928 | + } |
---|
929 | + |
---|
930 | + void readAttributes(std::istream& is) { |
---|
931 | + |
---|
932 | + std::vector<std::string> maps; |
---|
933 | + std::string line; |
---|
934 | + |
---|
935 | + while (std::getline(is, line)) { |
---|
936 | + |
---|
937 | + std::istringstream ls(line); |
---|
938 | + |
---|
939 | + std::string attr, token; |
---|
940 | + |
---|
941 | + ls >> attr; |
---|
942 | + _reader_bits::readToken(ls, token); |
---|
943 | + |
---|
944 | + typename Attributes::iterator it = _attributes.lower_bound(attr); |
---|
945 | + while (it != _attributes.end() && it->first == attr) { |
---|
946 | + it->second->set(token); |
---|
947 | + it->second->touch(); |
---|
948 | + ++it; |
---|
949 | + } |
---|
950 | + } |
---|
951 | + for (typename Attributes::iterator it = _attributes.begin(); |
---|
952 | + it != _attributes.end(); ++it) { |
---|
953 | + if (!it->second->touched()) { |
---|
954 | + ErrorMessage msg; |
---|
955 | + msg << "Attribute not found in file: " << it->first; |
---|
956 | + throw IoParameterError(msg.message()); |
---|
957 | + } |
---|
958 | + } |
---|
959 | + } |
---|
960 | + |
---|
961 | + public: |
---|
962 | + |
---|
963 | + /// \e |
---|
964 | + void run() { |
---|
965 | + LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); |
---|
966 | + |
---|
967 | + bool node_set_done = false; |
---|
968 | + bool arc_set_done = false; |
---|
969 | + bool attributes_done = false; |
---|
970 | + |
---|
971 | + int line_num = 0; |
---|
972 | + std::string line; |
---|
973 | + |
---|
974 | + skipSection(*_is, line_num); |
---|
975 | + |
---|
976 | + while (++line_num, getline(*_is, line)) { |
---|
977 | + char buf[2048]; |
---|
978 | + _reader_bits::FilterStreamBuf buffer(*_is, line_num); |
---|
979 | + try { |
---|
980 | + buffer.pubsetbuf(buf, sizeof(buf)); |
---|
981 | + std::istream fs(&buffer); |
---|
982 | + |
---|
983 | + std::istringstream ls(line); |
---|
984 | + std::string section, caption; |
---|
985 | + ls >> section >> caption; |
---|
986 | + |
---|
987 | + if (section == "@nodeset" && !node_set_done) { |
---|
988 | + if (_node_set_caption.empty() || _node_set_caption == caption) { |
---|
989 | + readNodeSet(fs); |
---|
990 | + node_set_done = true; |
---|
991 | + } |
---|
992 | + } else if ((section == "@arcset" || section == "@edgeset") && |
---|
993 | + !arc_set_done) { |
---|
994 | + if (_arc_set_caption.empty() || _arc_set_caption == caption) { |
---|
995 | + readArcSet(fs); |
---|
996 | + arc_set_done = true; |
---|
997 | + } |
---|
998 | + } else if (section == "@attributes" && !attributes_done) { |
---|
999 | + if (_attributes_caption.empty() || _attributes_caption == caption) { |
---|
1000 | + readAttributes(fs); |
---|
1001 | + attributes_done = true; |
---|
1002 | + } |
---|
1003 | + } |
---|
1004 | + |
---|
1005 | + skipSection(*_is, line_num); |
---|
1006 | + } catch (DataFormatError& error) { |
---|
1007 | + error.line(buffer.line_num()); |
---|
1008 | + throw; |
---|
1009 | + } |
---|
1010 | + } |
---|
1011 | + |
---|
1012 | + } |
---|
1013 | + |
---|
1014 | + }; |
---|
1015 | + |
---|
1016 | + template <typename Digraph> |
---|
1017 | + DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) { |
---|
1018 | + return DigraphReader<Digraph>(is, digraph); |
---|
1019 | + } |
---|
1020 | + |
---|
1021 | + template <typename Digraph> |
---|
1022 | + DigraphReader<Digraph> digraphReader(const std::string& fn, |
---|
1023 | + Digraph& digraph) { |
---|
1024 | + return DigraphReader<Digraph>(fn, digraph); |
---|
1025 | + } |
---|
1026 | + |
---|
1027 | + template <typename Digraph> |
---|
1028 | + DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) { |
---|
1029 | + return DigraphReader<Digraph>(fn, digraph); |
---|
1030 | + } |
---|
1031 | +} |
---|
1032 | + |
---|
1033 | +#endif |
---|
1034 | diff -r b6bede534255 -r 988226bc5e6c lemon/lgf_writer.h |
---|
1035 | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
---|
1036 | +++ b/lemon/lgf_writer.h Thu Apr 10 10:20:00 2008 +0200 |
---|
1037 | @@ -0,0 +1,542 @@ |
---|
1038 | +/* -*- C++ -*- |
---|
1039 | + * |
---|
1040 | + * This file is a part of LEMON, a generic C++ optimization library |
---|
1041 | + * |
---|
1042 | + * Copyright (C) 2003-2008 |
---|
1043 | + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
---|
1044 | + * (Egervary Research Group on Combinatorial Optimization, EGRES). |
---|
1045 | + * |
---|
1046 | + * Permission to use, modify and distribute this software is granted |
---|
1047 | + * provided that this copyright notice appears in all copies. For |
---|
1048 | + * precise terms see the accompanying LICENSE file. |
---|
1049 | + * |
---|
1050 | + * This software is provided "AS IS" with no warranty of any kind, |
---|
1051 | + * express or implied, and with no claim as to its suitability for any |
---|
1052 | + * purpose. |
---|
1053 | + * |
---|
1054 | + */ |
---|
1055 | + |
---|
1056 | +///\ingroup lemon_io |
---|
1057 | +///\file |
---|
1058 | +///\brief Lemon Graph Format writer. |
---|
1059 | + |
---|
1060 | + |
---|
1061 | +#ifndef LEMON_LGF_WRITER_H |
---|
1062 | +#define LEMON_LGF_WRITER_H |
---|
1063 | + |
---|
1064 | +#include <iostream> |
---|
1065 | +#include <fstream> |
---|
1066 | +#include <sstream> |
---|
1067 | + |
---|
1068 | +#include <vector> |
---|
1069 | +#include <functional> |
---|
1070 | + |
---|
1071 | +#include <lemon/assert.h> |
---|
1072 | +#include <lemon/graph_utils.h> |
---|
1073 | + |
---|
1074 | +namespace lemon { |
---|
1075 | + |
---|
1076 | + namespace _writer_bits { |
---|
1077 | + |
---|
1078 | + template <typename Value> |
---|
1079 | + struct DefaultConverter { |
---|
1080 | + std::string operator()(const Value& value) { |
---|
1081 | + std::ostringstream os; |
---|
1082 | + os << value; |
---|
1083 | + return os.str(); |
---|
1084 | + } |
---|
1085 | + }; |
---|
1086 | + |
---|
1087 | + template <typename _Item> |
---|
1088 | + class MapStorageBase { |
---|
1089 | + public: |
---|
1090 | + typedef _Item Item; |
---|
1091 | + |
---|
1092 | + public: |
---|
1093 | + MapStorageBase() {} |
---|
1094 | + virtual ~MapStorageBase() {} |
---|
1095 | + |
---|
1096 | + virtual std::string get(const Item& item) = 0; |
---|
1097 | + |
---|
1098 | + }; |
---|
1099 | + |
---|
1100 | + template <typename _Item, typename _Map, |
---|
1101 | + typename _Converter = DefaultConverter<typename _Map::Value> > |
---|
1102 | + class MapStorage : public MapStorageBase<_Item> { |
---|
1103 | + public: |
---|
1104 | + typedef _Map Map; |
---|
1105 | + typedef _Converter Converter; |
---|
1106 | + typedef _Item Item; |
---|
1107 | + |
---|
1108 | + private: |
---|
1109 | + const Map& _map; |
---|
1110 | + Converter _converter; |
---|
1111 | + |
---|
1112 | + public: |
---|
1113 | + MapStorage(const Map& map, const Converter& converter = Converter()) |
---|
1114 | + : _map(map), _converter(converter) {} |
---|
1115 | + virtual ~MapStorage() {} |
---|
1116 | + |
---|
1117 | + virtual std::string get(const Item& item) { |
---|
1118 | + return _converter(_map[item]); |
---|
1119 | + } |
---|
1120 | + }; |
---|
1121 | + |
---|
1122 | + class ValueStorageBase { |
---|
1123 | + public: |
---|
1124 | + ValueStorageBase() {} |
---|
1125 | + virtual ~ValueStorageBase() {} |
---|
1126 | + |
---|
1127 | + virtual std::string get() = 0; |
---|
1128 | + }; |
---|
1129 | + |
---|
1130 | + template <typename _Value, typename _Converter = DefaultConverter<_Value> > |
---|
1131 | + class ValueStorage : public ValueStorageBase { |
---|
1132 | + public: |
---|
1133 | + typedef _Value Value; |
---|
1134 | + typedef _Converter Converter; |
---|
1135 | + |
---|
1136 | + private: |
---|
1137 | + const Value& _value; |
---|
1138 | + Converter _converter; |
---|
1139 | + |
---|
1140 | + public: |
---|
1141 | + ValueStorage(const Value& value, const Converter& converter = Converter()) |
---|
1142 | + : _value(value), _converter(converter) {} |
---|
1143 | + |
---|
1144 | + virtual std::string get() { |
---|
1145 | + return _converter(_value); |
---|
1146 | + } |
---|
1147 | + }; |
---|
1148 | + |
---|
1149 | + template <typename Value> |
---|
1150 | + struct MapLookUpConverter { |
---|
1151 | + const std::map<Value, std::string>& _map; |
---|
1152 | + |
---|
1153 | + MapLookUpConverter(const std::map<Value, std::string>& map) |
---|
1154 | + : _map(map) {} |
---|
1155 | + |
---|
1156 | + std::string operator()(const Value& str) { |
---|
1157 | + typename std::map<Value, std::string>::const_iterator it = |
---|
1158 | + _map.find(str); |
---|
1159 | + if (it == _map.end()) { |
---|
1160 | + std::ostringstream msg; |
---|
1161 | + msg << "Item not found"; |
---|
1162 | + throw DataFormatError("Item not found"); |
---|
1163 | + } |
---|
1164 | + return it->second; |
---|
1165 | + } |
---|
1166 | + }; |
---|
1167 | + |
---|
1168 | + bool isWhiteSpace(char c) { |
---|
1169 | + return c == ' ' || c == '\t' || c == '\v' || |
---|
1170 | + c == '\n' || c == '\r' || c == '\f'; |
---|
1171 | + } |
---|
1172 | + |
---|
1173 | + bool isEscaped(char c) { |
---|
1174 | + return c == '\\' || c == '\"' || c == '\'' || |
---|
1175 | + c == '\a' || c == '\b'; |
---|
1176 | + } |
---|
1177 | + |
---|
1178 | + static void writeEscape(std::ostream& os, char c) { |
---|
1179 | + switch (c) { |
---|
1180 | + case '\\': |
---|
1181 | + os << "\\\\"; |
---|
1182 | + return; |
---|
1183 | + case '\"': |
---|
1184 | + os << "\\\""; |
---|
1185 | + return; |
---|
1186 | + case '\a': |
---|
1187 | + os << "\\a"; |
---|
1188 | + return; |
---|
1189 | + case '\b': |
---|
1190 | + os << "\\b"; |
---|
1191 | + return; |
---|
1192 | + case '\f': |
---|
1193 | + os << "\\f"; |
---|
1194 | + return; |
---|
1195 | + case '\r': |
---|
1196 | + os << "\\r"; |
---|
1197 | + return; |
---|
1198 | + case '\n': |
---|
1199 | + os << "\\n"; |
---|
1200 | + return; |
---|
1201 | + case '\t': |
---|
1202 | + os << "\\t"; |
---|
1203 | + return; |
---|
1204 | + case '\v': |
---|
1205 | + os << "\\v"; |
---|
1206 | + return; |
---|
1207 | + default: |
---|
1208 | + if (c < 0x20) { |
---|
1209 | + os << '\\' << std::oct << static_cast<int>(c); |
---|
1210 | + } else { |
---|
1211 | + os << c; |
---|
1212 | + } |
---|
1213 | + return; |
---|
1214 | + } |
---|
1215 | + } |
---|
1216 | + |
---|
1217 | + bool requireEscape(const std::string& str) { |
---|
1218 | + std::istringstream is(str); |
---|
1219 | + char c; |
---|
1220 | + while (is.get(c)) { |
---|
1221 | + if (isWhiteSpace(c) || isEscaped(c)) { |
---|
1222 | + return true; |
---|
1223 | + } |
---|
1224 | + } |
---|
1225 | + return false; |
---|
1226 | + } |
---|
1227 | + |
---|
1228 | + std::ostream& writeToken(std::ostream& os, const std::string& str) { |
---|
1229 | + |
---|
1230 | + if (requireEscape(str)) { |
---|
1231 | + os << '\"'; |
---|
1232 | + for (std::string::const_iterator it = str.begin(); |
---|
1233 | + it != str.end(); ++it) { |
---|
1234 | + writeEscape(os, *it); |
---|
1235 | + } |
---|
1236 | + os << '\"'; |
---|
1237 | + } else { |
---|
1238 | + os << str; |
---|
1239 | + } |
---|
1240 | + return os; |
---|
1241 | + } |
---|
1242 | + |
---|
1243 | + } |
---|
1244 | + |
---|
1245 | + /// \e |
---|
1246 | + template <typename _Digraph> |
---|
1247 | + class DigraphWriter { |
---|
1248 | + public: |
---|
1249 | + |
---|
1250 | + typedef _Digraph Digraph; |
---|
1251 | + GRAPH_TYPEDEFS(typename Digraph); |
---|
1252 | + |
---|
1253 | + private: |
---|
1254 | + |
---|
1255 | + |
---|
1256 | + std::ostream* _os; |
---|
1257 | + bool local_os; |
---|
1258 | + |
---|
1259 | + Digraph& _digraph; |
---|
1260 | + |
---|
1261 | + std::string _node_set_caption; |
---|
1262 | + std::string _arc_set_caption; |
---|
1263 | + std::string _attributes_caption; |
---|
1264 | + |
---|
1265 | + typedef std::map<Node, std::string> NodeIndex; |
---|
1266 | + NodeIndex _node_index; |
---|
1267 | + typedef std::map<Arc, std::string> ArcIndex; |
---|
1268 | + ArcIndex _arc_index; |
---|
1269 | + |
---|
1270 | + typedef std::vector<std::pair<std::string, |
---|
1271 | + _writer_bits::MapStorageBase<Node>* > > NodeMaps; |
---|
1272 | + NodeMaps _node_maps; |
---|
1273 | + |
---|
1274 | + typedef std::vector<std::pair<std::string, |
---|
1275 | + _writer_bits::MapStorageBase<Arc>* > >ArcMaps; |
---|
1276 | + ArcMaps _arc_maps; |
---|
1277 | + |
---|
1278 | + typedef std::vector<std::pair<std::string, |
---|
1279 | + _writer_bits::ValueStorageBase*> > Attributes; |
---|
1280 | + Attributes _attributes; |
---|
1281 | + |
---|
1282 | + public: |
---|
1283 | + |
---|
1284 | + /// \e |
---|
1285 | + DigraphWriter(std::ostream& is, Digraph& digraph) |
---|
1286 | + : _os(&is), local_os(false), _digraph(digraph) {} |
---|
1287 | + |
---|
1288 | + /// \e |
---|
1289 | + DigraphWriter(const std::string& fn, Digraph& digraph) |
---|
1290 | + : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph) {} |
---|
1291 | + |
---|
1292 | + /// \e |
---|
1293 | + DigraphWriter(const char* fn, Digraph& digraph) |
---|
1294 | + : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph) {} |
---|
1295 | + |
---|
1296 | + DigraphWriter(DigraphWriter& other) |
---|
1297 | + : _os(other._os), local_os(other.local_os), _digraph(other._digraph) { |
---|
1298 | + |
---|
1299 | + other.is = 0; |
---|
1300 | + other.local_os = false; |
---|
1301 | + |
---|
1302 | + _node_index.swap(other._node_index); |
---|
1303 | + _arc_index.swap(other._arc_index); |
---|
1304 | + |
---|
1305 | + _node_maps.swap(other._node_maps); |
---|
1306 | + _arc_maps.swap(other._arc_maps); |
---|
1307 | + _attributes.swap(other._attributes); |
---|
1308 | + |
---|
1309 | + _node_set_caption = other._node_set_caption; |
---|
1310 | + _arc_set_caption = other._arc_set_caption; |
---|
1311 | + _attributes_caption = other._attributes_caption; |
---|
1312 | + } |
---|
1313 | + |
---|
1314 | + /// \e |
---|
1315 | + ~DigraphWriter() { |
---|
1316 | + for (typename NodeMaps::iterator it = _node_maps.begin(); |
---|
1317 | + it != _node_maps.end(); ++it) { |
---|
1318 | + delete it->second; |
---|
1319 | + } |
---|
1320 | + |
---|
1321 | + for (typename ArcMaps::iterator it = _arc_maps.begin(); |
---|
1322 | + it != _arc_maps.end(); ++it) { |
---|
1323 | + delete it->second; |
---|
1324 | + } |
---|
1325 | + |
---|
1326 | + for (typename Attributes::iterator it = _attributes.begin(); |
---|
1327 | + it != _attributes.end(); ++it) { |
---|
1328 | + delete it->second; |
---|
1329 | + } |
---|
1330 | + |
---|
1331 | + if (local_os) { |
---|
1332 | + delete _os; |
---|
1333 | + } |
---|
1334 | + } |
---|
1335 | + |
---|
1336 | + private: |
---|
1337 | + |
---|
1338 | + DigraphWriter& operator=(const DigraphWriter&); |
---|
1339 | + |
---|
1340 | + public: |
---|
1341 | + |
---|
1342 | + /// \e |
---|
1343 | + template <typename Map> |
---|
1344 | + DigraphWriter& nodeMap(const std::string& caption, const Map& map) { |
---|
1345 | + _writer_bits::MapStorageBase<Node>* storage = |
---|
1346 | + new _writer_bits::MapStorage<Node, Map>(map); |
---|
1347 | + _node_maps.push_back(std::make_pair(caption, storage)); |
---|
1348 | + return *this; |
---|
1349 | + } |
---|
1350 | + |
---|
1351 | + /// \e |
---|
1352 | + template <typename Map, typename Converter> |
---|
1353 | + DigraphWriter& nodeMap(const std::string& caption, const Map& map, |
---|
1354 | + const Converter& converter = Converter()) { |
---|
1355 | + _writer_bits::MapStorageBase<Node>* storage = |
---|
1356 | + new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); |
---|
1357 | + _node_maps.push_back(std::make_pair(caption, storage)); |
---|
1358 | + return *this; |
---|
1359 | + } |
---|
1360 | + |
---|
1361 | + /// \e |
---|
1362 | + template <typename Map> |
---|
1363 | + DigraphWriter& arcMap(const std::string& caption, const Map& map) { |
---|
1364 | + _writer_bits::MapStorageBase<Arc>* storage = |
---|
1365 | + new _writer_bits::MapStorage<Arc, Map>(map); |
---|
1366 | + _arc_maps.push_back(std::make_pair(caption, storage)); |
---|
1367 | + return *this; |
---|
1368 | + } |
---|
1369 | + |
---|
1370 | + /// \e |
---|
1371 | + template <typename Map, typename Converter> |
---|
1372 | + DigraphWriter& arcMap(const std::string& caption, const Map& map, |
---|
1373 | + const Converter& converter = Converter()) { |
---|
1374 | + _writer_bits::MapStorageBase<Arc>* storage = |
---|
1375 | + new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter); |
---|
1376 | + _arc_maps.push_back(std::make_pair(caption, storage)); |
---|
1377 | + return *this; |
---|
1378 | + } |
---|
1379 | + |
---|
1380 | + /// \e |
---|
1381 | + template <typename Value> |
---|
1382 | + DigraphWriter& attribute(const std::string& caption, const Value& value) { |
---|
1383 | + _writer_bits::ValueStorageBase* storage = |
---|
1384 | + new _writer_bits::ValueStorage<Value>(value); |
---|
1385 | + _attributes.push_back(std::make_pair(caption, storage)); |
---|
1386 | + return *this; |
---|
1387 | + } |
---|
1388 | + |
---|
1389 | + /// \e |
---|
1390 | + template <typename Value, typename Converter> |
---|
1391 | + DigraphWriter& attribute(const std::string& caption, const Value& value, |
---|
1392 | + const Converter& converter = Converter()) { |
---|
1393 | + _writer_bits::ValueStorageBase* storage = |
---|
1394 | + new _writer_bits::ValueStorage<Value, Converter>(value, converter); |
---|
1395 | + _attributes.push_back(std::make_pair(caption, storage)); |
---|
1396 | + return *this; |
---|
1397 | + } |
---|
1398 | + |
---|
1399 | + /// \e |
---|
1400 | + DigraphWriter& node(const std::string& caption, const Node& node) { |
---|
1401 | + typedef _writer_bits::MapLookUpConverter<Node> Converter; |
---|
1402 | + Converter converter(_node_index); |
---|
1403 | + _writer_bits::ValueStorageBase* storage = |
---|
1404 | + new _writer_bits::ValueStorage<Node, Converter>(node, converter); |
---|
1405 | + _attributes.push_back(std::make_pair(caption, storage)); |
---|
1406 | + return *this; |
---|
1407 | + } |
---|
1408 | + |
---|
1409 | + /// \e |
---|
1410 | + DigraphWriter& arc(const std::string& caption, const Arc& arc) { |
---|
1411 | + typedef _writer_bits::MapLookUpConverter<Arc> Converter; |
---|
1412 | + Converter converter(_arc_index); |
---|
1413 | + _writer_bits::ValueStorageBase* storage = |
---|
1414 | + new _writer_bits::ValueStorage<Arc, Converter>(arc, converter); |
---|
1415 | + _attributes.push_back(std::make_pair(caption, storage)); |
---|
1416 | + return *this; |
---|
1417 | + } |
---|
1418 | + |
---|
1419 | + /// \e |
---|
1420 | + DigraphWriter& nodeSet(const std::string& caption) { |
---|
1421 | + _node_set_caption = caption; |
---|
1422 | + return *this; |
---|
1423 | + } |
---|
1424 | + |
---|
1425 | + /// \e |
---|
1426 | + DigraphWriter& arcSet(const std::string& caption) { |
---|
1427 | + _arc_set_caption = caption; |
---|
1428 | + return *this; |
---|
1429 | + } |
---|
1430 | + |
---|
1431 | + /// \e |
---|
1432 | + DigraphWriter& attributes(const std::string& caption) { |
---|
1433 | + _attributes_caption = caption; |
---|
1434 | + return *this; |
---|
1435 | + } |
---|
1436 | + |
---|
1437 | + private: |
---|
1438 | + |
---|
1439 | + void writeNodeSet() { |
---|
1440 | + bool _write_label = true; |
---|
1441 | + for (typename NodeMaps::iterator it = _node_maps.begin(); |
---|
1442 | + it != _node_maps.end(); ++it) { |
---|
1443 | + if (it->first == "label") { |
---|
1444 | + _write_label = false; |
---|
1445 | + } |
---|
1446 | + } |
---|
1447 | + |
---|
1448 | + *_os << "@nodeset"; |
---|
1449 | + if (!_node_set_caption.empty()) { |
---|
1450 | + *_os << ' ' << _node_set_caption; |
---|
1451 | + } |
---|
1452 | + *_os << std::endl; |
---|
1453 | + |
---|
1454 | + if (_write_label) { |
---|
1455 | + *_os << "label" << '\t'; |
---|
1456 | + } |
---|
1457 | + for (typename NodeMaps::iterator it = _node_maps.begin(); |
---|
1458 | + it != _node_maps.end(); ++it) { |
---|
1459 | + *_os << it->first << '\t'; |
---|
1460 | + } |
---|
1461 | + *_os << std::endl; |
---|
1462 | + |
---|
1463 | + for (NodeIt n(_digraph); n != INVALID; ++n) { |
---|
1464 | + if (_write_label) { |
---|
1465 | + std::ostringstream os; |
---|
1466 | + os << _digraph.id(n); |
---|
1467 | + _writer_bits::writeToken(*_os, os.str()); |
---|
1468 | + *_os << '\t'; |
---|
1469 | + _node_index.insert(std::make_pair(n, os.str())); |
---|
1470 | + } |
---|
1471 | + for (typename NodeMaps::iterator it = _node_maps.begin(); |
---|
1472 | + it != _node_maps.end(); ++it) { |
---|
1473 | + std::string value = it->second->get(n); |
---|
1474 | + _writer_bits::writeToken(*_os, value); |
---|
1475 | + if (it->first == "label") { |
---|
1476 | + _node_index.insert(std::make_pair(n, value)); |
---|
1477 | + } |
---|
1478 | + *_os << '\t'; |
---|
1479 | + } |
---|
1480 | + *_os << std::endl; |
---|
1481 | + } |
---|
1482 | + } |
---|
1483 | + |
---|
1484 | + void writeArcSet() { |
---|
1485 | + bool _write_label = true; |
---|
1486 | + for (typename ArcMaps::iterator it = _arc_maps.begin(); |
---|
1487 | + it != _arc_maps.end(); ++it) { |
---|
1488 | + if (it->first == "label") { |
---|
1489 | + _write_label = false; |
---|
1490 | + } |
---|
1491 | + } |
---|
1492 | + |
---|
1493 | + *_os << "@arcset"; |
---|
1494 | + if (!_arc_set_caption.empty()) { |
---|
1495 | + *_os << ' ' << _arc_set_caption; |
---|
1496 | + } |
---|
1497 | + *_os << std::endl; |
---|
1498 | + |
---|
1499 | + *_os << '\t' << '\t'; |
---|
1500 | + if (_write_label) { |
---|
1501 | + *_os << "label" << '\t'; |
---|
1502 | + } |
---|
1503 | + for (typename ArcMaps::iterator it = _arc_maps.begin(); |
---|
1504 | + it != _arc_maps.end(); ++it) { |
---|
1505 | + *_os << it->first << '\t'; |
---|
1506 | + } |
---|
1507 | + *_os << std::endl; |
---|
1508 | + |
---|
1509 | + for (ArcIt a(_digraph); a != INVALID; ++a) { |
---|
1510 | + _writer_bits::writeToken(*_os, _node_index. |
---|
1511 | + find(_digraph.source(a))->second); |
---|
1512 | + *_os << '\t'; |
---|
1513 | + _writer_bits::writeToken(*_os, _node_index. |
---|
1514 | + find(_digraph.target(a))->second); |
---|
1515 | + *_os << '\t'; |
---|
1516 | + if (_write_label) { |
---|
1517 | + std::ostringstream os; |
---|
1518 | + os << _digraph.id(a); |
---|
1519 | + _writer_bits::writeToken(*_os, os.str()); |
---|
1520 | + *_os << '\t'; |
---|
1521 | + _arc_index.insert(std::make_pair(a, os.str())); |
---|
1522 | + } |
---|
1523 | + for (typename ArcMaps::iterator it = _arc_maps.begin(); |
---|
1524 | + it != _arc_maps.end(); ++it) { |
---|
1525 | + std::string value = it->second->get(a); |
---|
1526 | + _writer_bits::writeToken(*_os, value); |
---|
1527 | + if (it->first == "label") { |
---|
1528 | + _arc_index.insert(std::make_pair(a, value)); |
---|
1529 | + } |
---|
1530 | + *_os << '\t'; |
---|
1531 | + } |
---|
1532 | + *_os << std::endl; |
---|
1533 | + } |
---|
1534 | + } |
---|
1535 | + |
---|
1536 | + void writeAttributes() { |
---|
1537 | + if (_attributes.empty()) return; |
---|
1538 | + *_os << "@attributes"; |
---|
1539 | + if (!_attributes_caption.empty()) { |
---|
1540 | + *_os << ' ' << _attributes_caption; |
---|
1541 | + } |
---|
1542 | + *_os << std::endl; |
---|
1543 | + for (typename Attributes::iterator it = _attributes.begin(); |
---|
1544 | + it != _attributes.end(); ++it) { |
---|
1545 | + *_os << it->first << ' '; |
---|
1546 | + _writer_bits::writeToken(*_os, it->second->get()); |
---|
1547 | + *_os << std::endl; |
---|
1548 | + } |
---|
1549 | + } |
---|
1550 | + |
---|
1551 | + public: |
---|
1552 | + |
---|
1553 | + /// \e |
---|
1554 | + void run() { |
---|
1555 | + writeNodeSet(); |
---|
1556 | + writeArcSet(); |
---|
1557 | + writeAttributes(); |
---|
1558 | + } |
---|
1559 | + |
---|
1560 | + }; |
---|
1561 | + |
---|
1562 | + template <typename Digraph> |
---|
1563 | + DigraphWriter<Digraph> digraphWriter(std::istream& is, Digraph& digraph) { |
---|
1564 | + return DigraphWriter<Digraph>(is, digraph); |
---|
1565 | + } |
---|
1566 | + |
---|
1567 | + template <typename Digraph> |
---|
1568 | + DigraphWriter<Digraph> digraphWriter(const std::string& fn, |
---|
1569 | + Digraph& digraph) { |
---|
1570 | + return DigraphWriter<Digraph>(fn, digraph); |
---|
1571 | + } |
---|
1572 | + |
---|
1573 | + template <typename Digraph> |
---|
1574 | + DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) { |
---|
1575 | + return DigraphWriter<Digraph>(fn, digraph); |
---|
1576 | + } |
---|
1577 | +} |
---|
1578 | + |
---|
1579 | +#endif |
---|
1580 | # HG changeset patch |
---|
1581 | # User Balazs Dezso <deba@inf.elte.hu> |
---|
1582 | # Date 1207839002 -7200 |
---|
1583 | # Node ID 7174a0d8102dd0ea4c5c84b78bcd75433d839375 |
---|
1584 | # Parent 988226bc5e6c092db643ebcb020e0a9e38f08dd0 |
---|
1585 | Several changes in lgf IO |
---|
1586 | |
---|
1587 | - Manual handling comments and section delimiters instead of FilterStreamBuf |
---|
1588 | - Renaming nodeset and arcset |
---|
1589 | - Reading full line in attributes |
---|
1590 | |
---|
1591 | diff -r 988226bc5e6c -r 7174a0d8102d lemon/lgf_reader.h |
---|
1592 | --- a/lemon/lgf_reader.h Thu Apr 10 10:20:00 2008 +0200 |
---|
1593 | +++ b/lemon/lgf_reader.h Thu Apr 10 16:50:02 2008 +0200 |
---|
1594 | @@ -134,160 +134,22 @@ namespace lemon { |
---|
1595 | } |
---|
1596 | }; |
---|
1597 | |
---|
1598 | - |
---|
1599 | - class FilterStreamBuf : public std::streambuf { |
---|
1600 | - public: |
---|
1601 | - |
---|
1602 | - typedef std::streambuf Parent; |
---|
1603 | - typedef Parent::char_type char_type; |
---|
1604 | - FilterStreamBuf(std::istream& is, int& num) |
---|
1605 | - : _is(is), _base(0), _eptr(0), |
---|
1606 | - _num(num), skip_state(after_endl) {} |
---|
1607 | - |
---|
1608 | - protected: |
---|
1609 | - |
---|
1610 | - enum skip_state_type { |
---|
1611 | - no_skip, |
---|
1612 | - after_endl, |
---|
1613 | - comment_line |
---|
1614 | - }; |
---|
1615 | - |
---|
1616 | - char_type small_buf[1]; |
---|
1617 | - |
---|
1618 | - |
---|
1619 | - std::istream& _is; |
---|
1620 | - |
---|
1621 | - char_type* _base; |
---|
1622 | - char_type* _eptr; |
---|
1623 | - |
---|
1624 | - int& _num; |
---|
1625 | - |
---|
1626 | - skip_state_type skip_state; |
---|
1627 | - |
---|
1628 | - |
---|
1629 | - char_type* base() { return _base; } |
---|
1630 | - char_type* eptr() { return _eptr; } |
---|
1631 | - int_type blen() { return _eptr - _base; } |
---|
1632 | - |
---|
1633 | - void setb(char_type* buf, int_type len) { |
---|
1634 | - _base = buf; |
---|
1635 | - _eptr = buf + len; |
---|
1636 | - } |
---|
1637 | - |
---|
1638 | - virtual std::streambuf* setbuf(char *buf, std::streamsize len) { |
---|
1639 | - if (base()) return 0; |
---|
1640 | - if (buf != 0 && len >= int(sizeof(small_buf))) { |
---|
1641 | - setb(buf, len); |
---|
1642 | - } else { |
---|
1643 | - setb(small_buf, sizeof(small_buf)); |
---|
1644 | - } |
---|
1645 | - setg(0, 0, 0); |
---|
1646 | - return this; |
---|
1647 | - } |
---|
1648 | - |
---|
1649 | - bool put_char(char c) { |
---|
1650 | - switch (skip_state) { |
---|
1651 | - case no_skip: |
---|
1652 | - switch (c) { |
---|
1653 | - case '\n': |
---|
1654 | - skip_state = after_endl; |
---|
1655 | - return true; |
---|
1656 | - default: |
---|
1657 | - return true; |
---|
1658 | - } |
---|
1659 | - case after_endl: |
---|
1660 | - switch (c) { |
---|
1661 | - case '@': |
---|
1662 | - return false; |
---|
1663 | - case '\n': |
---|
1664 | - return false; |
---|
1665 | - case '#': |
---|
1666 | - skip_state = comment_line; |
---|
1667 | - return false; |
---|
1668 | - default: |
---|
1669 | - if (!isspace(c)) { |
---|
1670 | - skip_state = no_skip; |
---|
1671 | - return true; |
---|
1672 | - } else { |
---|
1673 | - return false; |
---|
1674 | - } |
---|
1675 | - } |
---|
1676 | - break; |
---|
1677 | - case comment_line: |
---|
1678 | - switch (c) { |
---|
1679 | - case '\n': |
---|
1680 | - skip_state = after_endl; |
---|
1681 | - return false; |
---|
1682 | - default: |
---|
1683 | - return false; |
---|
1684 | - } |
---|
1685 | - } |
---|
1686 | - return false; |
---|
1687 | - } |
---|
1688 | - |
---|
1689 | - virtual int_type underflow() { |
---|
1690 | - char c; |
---|
1691 | - if ((c = _is.peek()) != EOF) { |
---|
1692 | - if (c == '@') { |
---|
1693 | - return EOF; |
---|
1694 | - } |
---|
1695 | - } else { |
---|
1696 | - return EOF; |
---|
1697 | - } |
---|
1698 | - char_type *ptr; |
---|
1699 | - for (ptr = base(); ptr != eptr(); ++ptr) { |
---|
1700 | - if ((c = _is.get()) != EOF) { |
---|
1701 | - if (c == '\n') ++_num; |
---|
1702 | - if (put_char(c)) { |
---|
1703 | - *ptr = c; |
---|
1704 | - } else { |
---|
1705 | - if (skip_state == after_endl && c == '@') { |
---|
1706 | - _is.putback(c); |
---|
1707 | - break; |
---|
1708 | - } |
---|
1709 | - --ptr; |
---|
1710 | - } |
---|
1711 | - } else { |
---|
1712 | - break; |
---|
1713 | - } |
---|
1714 | - } |
---|
1715 | - setg(base(), base(), ptr); |
---|
1716 | - return *base(); |
---|
1717 | - } |
---|
1718 | - |
---|
1719 | - virtual int_type sync() { |
---|
1720 | - return EOF; |
---|
1721 | - } |
---|
1722 | - |
---|
1723 | - public: |
---|
1724 | - |
---|
1725 | - int line_num() const { |
---|
1726 | - int r = _num; |
---|
1727 | - for (char_type* p = gptr(); p != egptr(); ++p) { |
---|
1728 | - if (*p == '\n') --r; |
---|
1729 | - } |
---|
1730 | - return r; |
---|
1731 | - } |
---|
1732 | - |
---|
1733 | - }; |
---|
1734 | - |
---|
1735 | template <typename Value> |
---|
1736 | struct MapLookUpConverter { |
---|
1737 | const std::map<std::string, Value>& _map; |
---|
1738 | - |
---|
1739 | - MapLookUpConverter(const std::map<std::string, Value>& map) |
---|
1740 | - : _map(map) {} |
---|
1741 | - |
---|
1742 | + |
---|
1743 | + MapLookUpConverter(const std::map<std::string, Value>& map) |
---|
1744 | + : _map(map) {} |
---|
1745 | + |
---|
1746 | Value operator()(const std::string& str) { |
---|
1747 | - typename std::map<std::string, Value>::const_iterator it = |
---|
1748 | - _map.find(str); |
---|
1749 | - |
---|
1750 | - if (it == _map.end()) { |
---|
1751 | - std::ostringstream msg; |
---|
1752 | - msg << "Item not found: " << str; |
---|
1753 | - throw DataFormatError(msg.str().c_str()); |
---|
1754 | - } |
---|
1755 | - return it->second; |
---|
1756 | + typename std::map<std::string, Value>::const_iterator it = |
---|
1757 | + _map.find(str); |
---|
1758 | + if (it == _map.end()) { |
---|
1759 | + std::ostringstream msg; |
---|
1760 | + msg << "Item not found: " << str; |
---|
1761 | + throw DataFormatError(msg.str().c_str()); |
---|
1762 | + } |
---|
1763 | + return it->second; |
---|
1764 | } |
---|
1765 | }; |
---|
1766 | |
---|
1767 | @@ -369,8 +231,7 @@ namespace lemon { |
---|
1768 | } |
---|
1769 | } |
---|
1770 | } |
---|
1771 | - |
---|
1772 | - |
---|
1773 | + |
---|
1774 | std::istream& readToken(std::istream& is, std::string& str) { |
---|
1775 | std::ostringstream os; |
---|
1776 | |
---|
1777 | @@ -396,7 +257,7 @@ namespace lemon { |
---|
1778 | os << c; |
---|
1779 | } |
---|
1780 | if (!is) { |
---|
1781 | - is.setstate(std::ios_base::goodbit); |
---|
1782 | + is.clear(); |
---|
1783 | } else { |
---|
1784 | is.putback(c); |
---|
1785 | } |
---|
1786 | @@ -423,8 +284,8 @@ namespace lemon { |
---|
1787 | |
---|
1788 | Digraph& _digraph; |
---|
1789 | |
---|
1790 | - std::string _node_set_caption; |
---|
1791 | - std::string _arc_set_caption; |
---|
1792 | + std::string _nodes_caption; |
---|
1793 | + std::string _arcs_caption; |
---|
1794 | std::string _attributes_caption; |
---|
1795 | |
---|
1796 | typedef std::map<std::string, Node> NodeIndex; |
---|
1797 | @@ -443,6 +304,9 @@ namespace lemon { |
---|
1798 | typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> |
---|
1799 | Attributes; |
---|
1800 | Attributes _attributes; |
---|
1801 | + |
---|
1802 | + int line_num; |
---|
1803 | + std::istringstream line; |
---|
1804 | |
---|
1805 | public: |
---|
1806 | |
---|
1807 | @@ -471,8 +335,8 @@ namespace lemon { |
---|
1808 | _arc_maps.swap(other._arc_maps); |
---|
1809 | _attributes.swap(other._attributes); |
---|
1810 | |
---|
1811 | - _node_set_caption = other._node_set_caption; |
---|
1812 | - _arc_set_caption = other._arc_set_caption; |
---|
1813 | + _nodes_caption = other._nodes_caption; |
---|
1814 | + _arcs_caption = other._arcs_caption; |
---|
1815 | _attributes_caption = other._attributes_caption; |
---|
1816 | } |
---|
1817 | |
---|
1818 | @@ -582,14 +446,14 @@ namespace lemon { |
---|
1819 | } |
---|
1820 | |
---|
1821 | /// \e |
---|
1822 | - DigraphReader& nodeSet(const std::string& caption) { |
---|
1823 | - _node_set_caption = caption; |
---|
1824 | + DigraphReader& nodes(const std::string& caption) { |
---|
1825 | + _nodes_caption = caption; |
---|
1826 | return *this; |
---|
1827 | } |
---|
1828 | |
---|
1829 | /// \e |
---|
1830 | - DigraphReader& arcSet(const std::string& caption) { |
---|
1831 | - _arc_set_caption = caption; |
---|
1832 | + DigraphReader& arcs(const std::string& caption) { |
---|
1833 | + _arcs_caption = caption; |
---|
1834 | return *this; |
---|
1835 | } |
---|
1836 | |
---|
1837 | @@ -600,49 +464,39 @@ namespace lemon { |
---|
1838 | } |
---|
1839 | |
---|
1840 | private: |
---|
1841 | - |
---|
1842 | |
---|
1843 | - static void skipSection(std::istream& is, int& line_num) { |
---|
1844 | - enum skip_state_type { skip, after_endl }; |
---|
1845 | - |
---|
1846 | - skip_state_type skip_state = after_endl; |
---|
1847 | - char c; |
---|
1848 | - |
---|
1849 | - while ((c = is.get()) != EOF) { |
---|
1850 | - if (c == '\n') ++line_num; |
---|
1851 | - |
---|
1852 | - switch (skip_state) { |
---|
1853 | - case skip: |
---|
1854 | - if (c == '\n') skip_state = after_endl; |
---|
1855 | - break; |
---|
1856 | - case after_endl: |
---|
1857 | - switch (c) { |
---|
1858 | - case '@': |
---|
1859 | - is.putback(c); |
---|
1860 | - return; |
---|
1861 | - case '\n': |
---|
1862 | - continue; |
---|
1863 | - default: |
---|
1864 | - if (!isspace(c)) { |
---|
1865 | - skip_state = skip; |
---|
1866 | - } |
---|
1867 | - break; |
---|
1868 | - } |
---|
1869 | - } |
---|
1870 | + bool readLine() { |
---|
1871 | + std::string str; |
---|
1872 | + while(++line_num, std::getline(*_is, str)) { |
---|
1873 | + line.clear(); line.str(str); |
---|
1874 | + char c; |
---|
1875 | + if (line >> std::ws >> c && c != '#') { |
---|
1876 | + line.putback(c); |
---|
1877 | + return true; |
---|
1878 | + } |
---|
1879 | } |
---|
1880 | + return false; |
---|
1881 | } |
---|
1882 | |
---|
1883 | - void readNodeSet(std::istream& is) { |
---|
1884 | + bool readSuccess() { |
---|
1885 | + return static_cast<bool>(*_is); |
---|
1886 | + } |
---|
1887 | + |
---|
1888 | + void skipSection() { |
---|
1889 | + char c; |
---|
1890 | + while (readSuccess() && line >> std::ws >> c && c != '@') { |
---|
1891 | + readLine(); |
---|
1892 | + } |
---|
1893 | + line.putback(c); |
---|
1894 | + } |
---|
1895 | + |
---|
1896 | + void readNodes() { |
---|
1897 | |
---|
1898 | std::vector<std::string> maps; |
---|
1899 | - std::string line; |
---|
1900 | |
---|
1901 | - { |
---|
1902 | - std::getline(is, line); |
---|
1903 | - std::istringstream ls(line); |
---|
1904 | - |
---|
1905 | + if (readLine()) { |
---|
1906 | std::string map; |
---|
1907 | - while (ls >> map) { |
---|
1908 | + while (line >> map) { |
---|
1909 | maps.push_back(map); |
---|
1910 | |
---|
1911 | typename NodeMaps::iterator it = _node_maps.lower_bound(map); |
---|
1912 | @@ -661,14 +515,15 @@ namespace lemon { |
---|
1913 | } |
---|
1914 | } |
---|
1915 | } |
---|
1916 | - |
---|
1917 | - while (getline(is, line)) { |
---|
1918 | + |
---|
1919 | + char c; |
---|
1920 | + while (readLine() && line >> c && c != '@') { |
---|
1921 | + line.putback(c); |
---|
1922 | Node n = _digraph.addNode(); |
---|
1923 | |
---|
1924 | - std::istringstream ls(line); |
---|
1925 | for (int i = 0; i < static_cast<int>(maps.size()); ++i) { |
---|
1926 | std::string token; |
---|
1927 | - _reader_bits::readToken(ls, token); |
---|
1928 | + _reader_bits::readToken(line, token); |
---|
1929 | |
---|
1930 | typename NodeMaps::iterator it = _node_maps.lower_bound(maps[i]); |
---|
1931 | while (it != _node_maps.end() && it->first == maps[i]) { |
---|
1932 | @@ -681,20 +536,18 @@ namespace lemon { |
---|
1933 | } |
---|
1934 | } |
---|
1935 | } |
---|
1936 | + if (readSuccess()) { |
---|
1937 | + line.putback(c); |
---|
1938 | + } |
---|
1939 | } |
---|
1940 | |
---|
1941 | - void readArcSet(std::istream& is) { |
---|
1942 | + void readArcs() { |
---|
1943 | |
---|
1944 | std::vector<std::string> maps; |
---|
1945 | - std::string line; |
---|
1946 | - |
---|
1947 | - { |
---|
1948 | - |
---|
1949 | - std::getline(is, line); |
---|
1950 | - std::istringstream ls(line); |
---|
1951 | - |
---|
1952 | + |
---|
1953 | + if (readLine()) { |
---|
1954 | std::string map; |
---|
1955 | - while (ls >> map) { |
---|
1956 | + while (line >> map) { |
---|
1957 | maps.push_back(map); |
---|
1958 | |
---|
1959 | typename ArcMaps::iterator it = _arc_maps.lower_bound(map); |
---|
1960 | @@ -714,15 +567,16 @@ namespace lemon { |
---|
1961 | } |
---|
1962 | } |
---|
1963 | |
---|
1964 | - while (getline(is, line)) { |
---|
1965 | - std::istringstream ls(line); |
---|
1966 | + char c; |
---|
1967 | + while (readLine() && line >> c && c != '@') { |
---|
1968 | + line.putback(c); |
---|
1969 | |
---|
1970 | Node s, t; |
---|
1971 | { |
---|
1972 | std::string token; |
---|
1973 | typename NodeIndex::iterator it; |
---|
1974 | |
---|
1975 | - _reader_bits::readToken(ls, token); |
---|
1976 | + _reader_bits::readToken(line, token); |
---|
1977 | it = _node_index.find(token); |
---|
1978 | if (it == _node_index.end()) { |
---|
1979 | std::ostringstream msg; |
---|
1980 | @@ -731,7 +585,7 @@ namespace lemon { |
---|
1981 | } |
---|
1982 | s = it->second; |
---|
1983 | |
---|
1984 | - _reader_bits::readToken(ls, token); |
---|
1985 | + _reader_bits::readToken(line, token); |
---|
1986 | it = _node_index.find(token); |
---|
1987 | if (it == _node_index.end()) { |
---|
1988 | std::ostringstream msg; |
---|
1989 | @@ -745,7 +599,7 @@ namespace lemon { |
---|
1990 | |
---|
1991 | for (int i = 0; i < static_cast<int>(maps.size()); ++i) { |
---|
1992 | std::string token; |
---|
1993 | - _reader_bits::readToken(ls, token); |
---|
1994 | + _reader_bits::readToken(line, token); |
---|
1995 | |
---|
1996 | typename ArcMaps::iterator it = _arc_maps.lower_bound(maps[i]); |
---|
1997 | while (it != _arc_maps.end() && it->first == maps[i]) { |
---|
1998 | @@ -758,21 +612,22 @@ namespace lemon { |
---|
1999 | } |
---|
2000 | } |
---|
2001 | } |
---|
2002 | + if (readSuccess()) { |
---|
2003 | + line.putback(c); |
---|
2004 | + } |
---|
2005 | } |
---|
2006 | |
---|
2007 | - void readAttributes(std::istream& is) { |
---|
2008 | + void readAttributes() { |
---|
2009 | |
---|
2010 | std::vector<std::string> maps; |
---|
2011 | - std::string line; |
---|
2012 | |
---|
2013 | - while (std::getline(is, line)) { |
---|
2014 | - |
---|
2015 | - std::istringstream ls(line); |
---|
2016 | - |
---|
2017 | + char c; |
---|
2018 | + while (readLine() && line >> c && c != '@') { |
---|
2019 | + line.putback(c); |
---|
2020 | + |
---|
2021 | std::string attr, token; |
---|
2022 | - |
---|
2023 | - ls >> attr; |
---|
2024 | - _reader_bits::readToken(ls, token); |
---|
2025 | + line >> attr; |
---|
2026 | + std::getline(line >> std::ws, token); |
---|
2027 | |
---|
2028 | typename Attributes::iterator it = _attributes.lower_bound(attr); |
---|
2029 | while (it != _attributes.end() && it->first == attr) { |
---|
2030 | @@ -780,6 +635,9 @@ namespace lemon { |
---|
2031 | it->second->touch(); |
---|
2032 | ++it; |
---|
2033 | } |
---|
2034 | + } |
---|
2035 | + if (readSuccess()) { |
---|
2036 | + line.putback(c); |
---|
2037 | } |
---|
2038 | for (typename Attributes::iterator it = _attributes.begin(); |
---|
2039 | it != _attributes.end(); ++it) { |
---|
2040 | @@ -797,47 +655,39 @@ namespace lemon { |
---|
2041 | void run() { |
---|
2042 | LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); |
---|
2043 | |
---|
2044 | - bool node_set_done = false; |
---|
2045 | - bool arc_set_done = false; |
---|
2046 | + bool nodes_done = false; |
---|
2047 | + bool arcs_done = false; |
---|
2048 | bool attributes_done = false; |
---|
2049 | |
---|
2050 | - int line_num = 0; |
---|
2051 | - std::string line; |
---|
2052 | - |
---|
2053 | - skipSection(*_is, line_num); |
---|
2054 | + readLine(); |
---|
2055 | |
---|
2056 | - while (++line_num, getline(*_is, line)) { |
---|
2057 | - char buf[2048]; |
---|
2058 | - _reader_bits::FilterStreamBuf buffer(*_is, line_num); |
---|
2059 | + while (readSuccess()) { |
---|
2060 | + skipSection(); |
---|
2061 | try { |
---|
2062 | - buffer.pubsetbuf(buf, sizeof(buf)); |
---|
2063 | - std::istream fs(&buffer); |
---|
2064 | - |
---|
2065 | - std::istringstream ls(line); |
---|
2066 | std::string section, caption; |
---|
2067 | - ls >> section >> caption; |
---|
2068 | + line >> section >> caption; |
---|
2069 | |
---|
2070 | - if (section == "@nodeset" && !node_set_done) { |
---|
2071 | - if (_node_set_caption.empty() || _node_set_caption == caption) { |
---|
2072 | - readNodeSet(fs); |
---|
2073 | - node_set_done = true; |
---|
2074 | + if (section == "@nodes" && !nodes_done) { |
---|
2075 | + if (_nodes_caption.empty() || _nodes_caption == caption) { |
---|
2076 | + readNodes(); |
---|
2077 | + nodes_done = true; |
---|
2078 | } |
---|
2079 | - } else if ((section == "@arcset" || section == "@edgeset") && |
---|
2080 | - !arc_set_done) { |
---|
2081 | - if (_arc_set_caption.empty() || _arc_set_caption == caption) { |
---|
2082 | - readArcSet(fs); |
---|
2083 | - arc_set_done = true; |
---|
2084 | + } else if ((section == "@arcs" || section == "@edges") && |
---|
2085 | + !arcs_done) { |
---|
2086 | + if (_arcs_caption.empty() || _arcs_caption == caption) { |
---|
2087 | + readArcs(); |
---|
2088 | + arcs_done = true; |
---|
2089 | } |
---|
2090 | } else if (section == "@attributes" && !attributes_done) { |
---|
2091 | if (_attributes_caption.empty() || _attributes_caption == caption) { |
---|
2092 | - readAttributes(fs); |
---|
2093 | + readAttributes(); |
---|
2094 | attributes_done = true; |
---|
2095 | } |
---|
2096 | } |
---|
2097 | |
---|
2098 | - skipSection(*_is, line_num); |
---|
2099 | + skipSection(); |
---|
2100 | } catch (DataFormatError& error) { |
---|
2101 | - error.line(buffer.line_num()); |
---|
2102 | + error.line(line_num); |
---|
2103 | throw; |
---|
2104 | } |
---|
2105 | } |
---|
2106 | diff -r 988226bc5e6c -r 7174a0d8102d lemon/lgf_writer.h |
---|
2107 | --- a/lemon/lgf_writer.h Thu Apr 10 10:20:00 2008 +0200 |
---|
2108 | +++ b/lemon/lgf_writer.h Thu Apr 10 16:50:02 2008 +0200 |
---|
2109 | @@ -120,8 +120,6 @@ namespace lemon { |
---|
2110 | typename std::map<Value, std::string>::const_iterator it = |
---|
2111 | _map.find(str); |
---|
2112 | if (it == _map.end()) { |
---|
2113 | - std::ostringstream msg; |
---|
2114 | - msg << "Item not found"; |
---|
2115 | throw DataFormatError("Item not found"); |
---|
2116 | } |
---|
2117 | return it->second; |
---|
2118 | @@ -221,8 +219,8 @@ namespace lemon { |
---|
2119 | |
---|
2120 | Digraph& _digraph; |
---|
2121 | |
---|
2122 | - std::string _node_set_caption; |
---|
2123 | - std::string _arc_set_caption; |
---|
2124 | + std::string _nodes_caption; |
---|
2125 | + std::string _arcs_caption; |
---|
2126 | std::string _attributes_caption; |
---|
2127 | |
---|
2128 | typedef std::map<Node, std::string> NodeIndex; |
---|
2129 | @@ -269,8 +267,8 @@ namespace lemon { |
---|
2130 | _arc_maps.swap(other._arc_maps); |
---|
2131 | _attributes.swap(other._attributes); |
---|
2132 | |
---|
2133 | - _node_set_caption = other._node_set_caption; |
---|
2134 | - _arc_set_caption = other._arc_set_caption; |
---|
2135 | + _nodes_caption = other._nodes_caption; |
---|
2136 | + _arcs_caption = other._arcs_caption; |
---|
2137 | _attributes_caption = other._attributes_caption; |
---|
2138 | } |
---|
2139 | |
---|
2140 | @@ -380,14 +378,14 @@ namespace lemon { |
---|
2141 | } |
---|
2142 | |
---|
2143 | /// \e |
---|
2144 | - DigraphWriter& nodeSet(const std::string& caption) { |
---|
2145 | - _node_set_caption = caption; |
---|
2146 | + DigraphWriter& nodes(const std::string& caption) { |
---|
2147 | + _nodes_caption = caption; |
---|
2148 | return *this; |
---|
2149 | } |
---|
2150 | |
---|
2151 | /// \e |
---|
2152 | - DigraphWriter& arcSet(const std::string& caption) { |
---|
2153 | - _arc_set_caption = caption; |
---|
2154 | + DigraphWriter& arcs(const std::string& caption) { |
---|
2155 | + _arcs_caption = caption; |
---|
2156 | return *this; |
---|
2157 | } |
---|
2158 | |
---|
2159 | @@ -399,7 +397,7 @@ namespace lemon { |
---|
2160 | |
---|
2161 | private: |
---|
2162 | |
---|
2163 | - void writeNodeSet() { |
---|
2164 | + void writeNodes() { |
---|
2165 | bool _write_label = true; |
---|
2166 | for (typename NodeMaps::iterator it = _node_maps.begin(); |
---|
2167 | it != _node_maps.end(); ++it) { |
---|
2168 | @@ -408,9 +406,9 @@ namespace lemon { |
---|
2169 | } |
---|
2170 | } |
---|
2171 | |
---|
2172 | - *_os << "@nodeset"; |
---|
2173 | - if (!_node_set_caption.empty()) { |
---|
2174 | - *_os << ' ' << _node_set_caption; |
---|
2175 | + *_os << "@nodes"; |
---|
2176 | + if (!_nodes_caption.empty()) { |
---|
2177 | + *_os << ' ' << _nodes_caption; |
---|
2178 | } |
---|
2179 | *_os << std::endl; |
---|
2180 | |
---|
2181 | @@ -444,7 +442,7 @@ namespace lemon { |
---|
2182 | } |
---|
2183 | } |
---|
2184 | |
---|
2185 | - void writeArcSet() { |
---|
2186 | + void writeArcs() { |
---|
2187 | bool _write_label = true; |
---|
2188 | for (typename ArcMaps::iterator it = _arc_maps.begin(); |
---|
2189 | it != _arc_maps.end(); ++it) { |
---|
2190 | @@ -453,9 +451,9 @@ namespace lemon { |
---|
2191 | } |
---|
2192 | } |
---|
2193 | |
---|
2194 | - *_os << "@arcset"; |
---|
2195 | - if (!_arc_set_caption.empty()) { |
---|
2196 | - *_os << ' ' << _arc_set_caption; |
---|
2197 | + *_os << "@arcs"; |
---|
2198 | + if (!_arcs_caption.empty()) { |
---|
2199 | + *_os << ' ' << _arcs_caption; |
---|
2200 | } |
---|
2201 | *_os << std::endl; |
---|
2202 | |
---|
2203 | @@ -515,8 +513,8 @@ namespace lemon { |
---|
2204 | |
---|
2205 | /// \e |
---|
2206 | void run() { |
---|
2207 | - writeNodeSet(); |
---|
2208 | - writeArcSet(); |
---|
2209 | + writeNodes(); |
---|
2210 | + writeArcs(); |
---|
2211 | writeAttributes(); |
---|
2212 | } |
---|
2213 | |
---|
2214 | # HG changeset patch |
---|
2215 | # User Balazs Dezso <deba@inf.elte.hu> |
---|
2216 | # Date 1207906639 -7200 |
---|
2217 | # Node ID 80086ce5c586577faaa0dba778d0ecbd4c5450ad |
---|
2218 | # Parent 7174a0d8102dd0ea4c5c84b78bcd75433d839375 |
---|
2219 | Several improvments in lgf IO |
---|
2220 | - More format checking code |
---|
2221 | - Better node and arc map reading |
---|
2222 | - Sorting arcs and nodes by label on writing |
---|
2223 | |
---|
2224 | diff -r 7174a0d8102d -r 80086ce5c586 lemon/lgf_reader.h |
---|
2225 | --- a/lemon/lgf_reader.h Thu Apr 10 16:50:02 2008 +0200 |
---|
2226 | +++ b/lemon/lgf_reader.h Fri Apr 11 11:37:19 2008 +0200 |
---|
2227 | @@ -484,7 +484,7 @@ namespace lemon { |
---|
2228 | |
---|
2229 | void skipSection() { |
---|
2230 | char c; |
---|
2231 | - while (readSuccess() && line >> std::ws >> c && c != '@') { |
---|
2232 | + while (readSuccess() && line >> c && c != '@') { |
---|
2233 | readLine(); |
---|
2234 | } |
---|
2235 | line.putback(c); |
---|
2236 | @@ -492,26 +492,39 @@ namespace lemon { |
---|
2237 | |
---|
2238 | void readNodes() { |
---|
2239 | |
---|
2240 | - std::vector<std::string> maps; |
---|
2241 | + std::vector<std::vector<_reader_bits::MapStorageBase<Node>*> > maps; |
---|
2242 | + int label = -1; |
---|
2243 | |
---|
2244 | if (readLine()) { |
---|
2245 | std::string map; |
---|
2246 | while (line >> map) { |
---|
2247 | - maps.push_back(map); |
---|
2248 | + |
---|
2249 | + if (map == "label") { |
---|
2250 | + label = maps.size(); |
---|
2251 | + } |
---|
2252 | + |
---|
2253 | + maps.push_back(std::vector<_reader_bits::MapStorageBase<Node>*>()); |
---|
2254 | |
---|
2255 | typename NodeMaps::iterator it = _node_maps.lower_bound(map); |
---|
2256 | while (it != _node_maps.end() && it->first == map) { |
---|
2257 | + if (it->second->touched()) { |
---|
2258 | + std::ostringstream msg; |
---|
2259 | + msg << "Multiple occurence of node map " << map; |
---|
2260 | + throw DataFormatError(msg.str().c_str()); |
---|
2261 | + } |
---|
2262 | + maps.back().push_back(it->second); |
---|
2263 | it->second->touch(); |
---|
2264 | ++it; |
---|
2265 | } |
---|
2266 | + |
---|
2267 | } |
---|
2268 | |
---|
2269 | for (typename NodeMaps::iterator it = _node_maps.begin(); |
---|
2270 | it != _node_maps.end(); ++it) { |
---|
2271 | if (!it->second->touched()) { |
---|
2272 | - ErrorMessage msg; |
---|
2273 | + std::ostringstream msg; |
---|
2274 | msg << "Map not found in file: " << it->first; |
---|
2275 | - throw IoParameterError(msg.message()); |
---|
2276 | + throw IoParameterError(msg.str().c_str()); |
---|
2277 | } |
---|
2278 | } |
---|
2279 | } |
---|
2280 | @@ -524,16 +537,19 @@ namespace lemon { |
---|
2281 | for (int i = 0; i < static_cast<int>(maps.size()); ++i) { |
---|
2282 | std::string token; |
---|
2283 | _reader_bits::readToken(line, token); |
---|
2284 | - |
---|
2285 | - typename NodeMaps::iterator it = _node_maps.lower_bound(maps[i]); |
---|
2286 | - while (it != _node_maps.end() && it->first == maps[i]) { |
---|
2287 | - it->second->set(n, token); |
---|
2288 | - ++it; |
---|
2289 | + |
---|
2290 | + for (int j = 0; j < static_cast<int>(maps[i].size()); ++j) { |
---|
2291 | + maps[i][j]->set(n, token); |
---|
2292 | } |
---|
2293 | |
---|
2294 | - if (maps[i] == "label") { |
---|
2295 | - _node_index[token] = n; |
---|
2296 | + if (label == i) { |
---|
2297 | + _node_index.insert(std::make_pair(token, n)); |
---|
2298 | } |
---|
2299 | + |
---|
2300 | + } |
---|
2301 | + |
---|
2302 | + if (line >> std::ws >> c) { |
---|
2303 | + throw DataFormatError("Extra character on the end of line"); |
---|
2304 | } |
---|
2305 | } |
---|
2306 | if (readSuccess()) { |
---|
2307 | @@ -543,15 +559,27 @@ namespace lemon { |
---|
2308 | |
---|
2309 | void readArcs() { |
---|
2310 | |
---|
2311 | - std::vector<std::string> maps; |
---|
2312 | - |
---|
2313 | - if (readLine()) { |
---|
2314 | + std::vector<std::vector<_reader_bits::MapStorageBase<Arc>*> > maps; |
---|
2315 | + int label = -1; |
---|
2316 | + |
---|
2317 | + if (readLine()) { |
---|
2318 | std::string map; |
---|
2319 | while (line >> map) { |
---|
2320 | - maps.push_back(map); |
---|
2321 | + |
---|
2322 | + if (map == "label") { |
---|
2323 | + label = maps.size(); |
---|
2324 | + } |
---|
2325 | + |
---|
2326 | + maps.push_back(std::vector<_reader_bits::MapStorageBase<Arc>*>()); |
---|
2327 | |
---|
2328 | typename ArcMaps::iterator it = _arc_maps.lower_bound(map); |
---|
2329 | while (it != _arc_maps.end() && it->first == map) { |
---|
2330 | + if (it->second->touched()) { |
---|
2331 | + std::ostringstream msg; |
---|
2332 | + msg << "Multiple occurence of arc map " << map; |
---|
2333 | + throw DataFormatError(msg.str().c_str()); |
---|
2334 | + } |
---|
2335 | + maps.back().push_back(it->second); |
---|
2336 | it->second->touch(); |
---|
2337 | ++it; |
---|
2338 | } |
---|
2339 | @@ -560,9 +588,9 @@ namespace lemon { |
---|
2340 | for (typename ArcMaps::iterator it = _arc_maps.begin(); |
---|
2341 | it != _arc_maps.end(); ++it) { |
---|
2342 | if (!it->second->touched()) { |
---|
2343 | - ErrorMessage msg; |
---|
2344 | + std::ostringstream msg; |
---|
2345 | msg << "Map not found in file: " << it->first; |
---|
2346 | - throw IoParameterError(msg.message()); |
---|
2347 | + throw IoParameterError(msg.str().c_str()); |
---|
2348 | } |
---|
2349 | } |
---|
2350 | } |
---|
2351 | @@ -600,16 +628,19 @@ namespace lemon { |
---|
2352 | for (int i = 0; i < static_cast<int>(maps.size()); ++i) { |
---|
2353 | std::string token; |
---|
2354 | _reader_bits::readToken(line, token); |
---|
2355 | - |
---|
2356 | - typename ArcMaps::iterator it = _arc_maps.lower_bound(maps[i]); |
---|
2357 | - while (it != _arc_maps.end() && it->first == maps[i]) { |
---|
2358 | - it->second->set(a, token); |
---|
2359 | - ++it; |
---|
2360 | + |
---|
2361 | + for (int j = 0; j < static_cast<int>(maps[i].size()); ++j) { |
---|
2362 | + maps[i][j]->set(a, token); |
---|
2363 | + } |
---|
2364 | + |
---|
2365 | + if (label == i) { |
---|
2366 | + _arc_index.insert(std::make_pair(token, a)); |
---|
2367 | } |
---|
2368 | |
---|
2369 | - if (maps[i] == "label") { |
---|
2370 | - _arc_index[token] = a; |
---|
2371 | - } |
---|
2372 | + } |
---|
2373 | + |
---|
2374 | + if (line >> std::ws >> c) { |
---|
2375 | + throw DataFormatError("Extra character on the end of line"); |
---|
2376 | } |
---|
2377 | } |
---|
2378 | if (readSuccess()) { |
---|
2379 | @@ -631,6 +662,11 @@ namespace lemon { |
---|
2380 | |
---|
2381 | typename Attributes::iterator it = _attributes.lower_bound(attr); |
---|
2382 | while (it != _attributes.end() && it->first == attr) { |
---|
2383 | + if (it->second->touched()) { |
---|
2384 | + std::ostringstream msg; |
---|
2385 | + msg << "Multiple occurence of attribute " << attr; |
---|
2386 | + throw DataFormatError(msg.str().c_str()); |
---|
2387 | + } |
---|
2388 | it->second->set(token); |
---|
2389 | it->second->touch(); |
---|
2390 | ++it; |
---|
2391 | @@ -642,9 +678,9 @@ namespace lemon { |
---|
2392 | for (typename Attributes::iterator it = _attributes.begin(); |
---|
2393 | it != _attributes.end(); ++it) { |
---|
2394 | if (!it->second->touched()) { |
---|
2395 | - ErrorMessage msg; |
---|
2396 | + std::ostringstream msg; |
---|
2397 | msg << "Attribute not found in file: " << it->first; |
---|
2398 | - throw IoParameterError(msg.message()); |
---|
2399 | + throw IoParameterError(msg.str().c_str()); |
---|
2400 | } |
---|
2401 | } |
---|
2402 | } |
---|
2403 | @@ -690,7 +726,19 @@ namespace lemon { |
---|
2404 | error.line(line_num); |
---|
2405 | throw; |
---|
2406 | } |
---|
2407 | - } |
---|
2408 | + } |
---|
2409 | + |
---|
2410 | + if (!nodes_done) { |
---|
2411 | + throw DataFormatError("Section @nodes not found"); |
---|
2412 | + } |
---|
2413 | + |
---|
2414 | + if (!arcs_done) { |
---|
2415 | + throw DataFormatError("Section @arcs not found"); |
---|
2416 | + } |
---|
2417 | + |
---|
2418 | + if (!attributes_done && !_attributes.empty()) { |
---|
2419 | + throw DataFormatError("Section @attributes not found"); |
---|
2420 | + } |
---|
2421 | |
---|
2422 | } |
---|
2423 | |
---|
2424 | diff -r 7174a0d8102d -r 80086ce5c586 lemon/lgf_writer.h |
---|
2425 | --- a/lemon/lgf_writer.h Thu Apr 10 16:50:02 2008 +0200 |
---|
2426 | +++ b/lemon/lgf_writer.h Fri Apr 11 11:37:19 2008 +0200 |
---|
2427 | @@ -28,6 +28,8 @@ |
---|
2428 | #include <fstream> |
---|
2429 | #include <sstream> |
---|
2430 | |
---|
2431 | +#include <algorithm> |
---|
2432 | + |
---|
2433 | #include <vector> |
---|
2434 | #include <functional> |
---|
2435 | |
---|
2436 | @@ -47,6 +49,28 @@ namespace lemon { |
---|
2437 | } |
---|
2438 | }; |
---|
2439 | |
---|
2440 | + template <typename T> |
---|
2441 | + bool operator<(const T&, const T&) { |
---|
2442 | + throw DataFormatError("Label map is not comparable"); |
---|
2443 | + } |
---|
2444 | + |
---|
2445 | + template <typename _Map> |
---|
2446 | + class MapLess { |
---|
2447 | + public: |
---|
2448 | + typedef _Map Map; |
---|
2449 | + typedef typename Map::Key Item; |
---|
2450 | + |
---|
2451 | + private: |
---|
2452 | + const Map& _map; |
---|
2453 | + |
---|
2454 | + public: |
---|
2455 | + MapLess(const Map& map) : _map(map) {} |
---|
2456 | + |
---|
2457 | + bool operator()(const Item& left, const Item& right) { |
---|
2458 | + return _map[left] < _map[right]; |
---|
2459 | + } |
---|
2460 | + }; |
---|
2461 | + |
---|
2462 | template <typename _Item> |
---|
2463 | class MapStorageBase { |
---|
2464 | public: |
---|
2465 | @@ -57,7 +81,7 @@ namespace lemon { |
---|
2466 | virtual ~MapStorageBase() {} |
---|
2467 | |
---|
2468 | virtual std::string get(const Item& item) = 0; |
---|
2469 | - |
---|
2470 | + virtual void sort(std::vector<Item>&) = 0; |
---|
2471 | }; |
---|
2472 | |
---|
2473 | template <typename _Item, typename _Map, |
---|
2474 | @@ -80,6 +104,10 @@ namespace lemon { |
---|
2475 | virtual std::string get(const Item& item) { |
---|
2476 | return _converter(_map[item]); |
---|
2477 | } |
---|
2478 | + virtual void sort(std::vector<Item>& items) { |
---|
2479 | + MapLess<Map> less(_map); |
---|
2480 | + std::sort(items.begin(), items.end(), less); |
---|
2481 | + } |
---|
2482 | }; |
---|
2483 | |
---|
2484 | class ValueStorageBase { |
---|
2485 | @@ -87,7 +115,7 @@ namespace lemon { |
---|
2486 | ValueStorageBase() {} |
---|
2487 | virtual ~ValueStorageBase() {} |
---|
2488 | |
---|
2489 | - virtual std::string get() = 0; |
---|
2490 | + virtual std::string get() = 0; |
---|
2491 | }; |
---|
2492 | |
---|
2493 | template <typename _Value, typename _Converter = DefaultConverter<_Value> > |
---|
2494 | @@ -398,11 +426,12 @@ namespace lemon { |
---|
2495 | private: |
---|
2496 | |
---|
2497 | void writeNodes() { |
---|
2498 | - bool _write_label = true; |
---|
2499 | + _writer_bits::MapStorageBase<Node>* label = 0; |
---|
2500 | for (typename NodeMaps::iterator it = _node_maps.begin(); |
---|
2501 | it != _node_maps.end(); ++it) { |
---|
2502 | if (it->first == "label") { |
---|
2503 | - _write_label = false; |
---|
2504 | + label = it->second; |
---|
2505 | + break; |
---|
2506 | } |
---|
2507 | } |
---|
2508 | |
---|
2509 | @@ -412,7 +441,7 @@ namespace lemon { |
---|
2510 | } |
---|
2511 | *_os << std::endl; |
---|
2512 | |
---|
2513 | - if (_write_label) { |
---|
2514 | + if (label == 0) { |
---|
2515 | *_os << "label" << '\t'; |
---|
2516 | } |
---|
2517 | for (typename NodeMaps::iterator it = _node_maps.begin(); |
---|
2518 | @@ -421,8 +450,22 @@ namespace lemon { |
---|
2519 | } |
---|
2520 | *_os << std::endl; |
---|
2521 | |
---|
2522 | + std::vector<Node> nodes; |
---|
2523 | for (NodeIt n(_digraph); n != INVALID; ++n) { |
---|
2524 | - if (_write_label) { |
---|
2525 | + nodes.push_back(n); |
---|
2526 | + } |
---|
2527 | + |
---|
2528 | + if (label == 0) { |
---|
2529 | + IdMap<Digraph, Node> id_map(_digraph); |
---|
2530 | + _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map); |
---|
2531 | + std::sort(nodes.begin(), nodes.end(), id_less); |
---|
2532 | + } else { |
---|
2533 | + label->sort(nodes); |
---|
2534 | + } |
---|
2535 | + |
---|
2536 | + for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { |
---|
2537 | + Node n = nodes[i]; |
---|
2538 | + if (label == 0) { |
---|
2539 | std::ostringstream os; |
---|
2540 | os << _digraph.id(n); |
---|
2541 | _writer_bits::writeToken(*_os, os.str()); |
---|
2542 | @@ -443,11 +486,12 @@ namespace lemon { |
---|
2543 | } |
---|
2544 | |
---|
2545 | void writeArcs() { |
---|
2546 | - bool _write_label = true; |
---|
2547 | + _writer_bits::MapStorageBase<Arc>* label = 0; |
---|
2548 | for (typename ArcMaps::iterator it = _arc_maps.begin(); |
---|
2549 | it != _arc_maps.end(); ++it) { |
---|
2550 | if (it->first == "label") { |
---|
2551 | - _write_label = false; |
---|
2552 | + label = it->second; |
---|
2553 | + break; |
---|
2554 | } |
---|
2555 | } |
---|
2556 | |
---|
2557 | @@ -458,7 +502,7 @@ namespace lemon { |
---|
2558 | *_os << std::endl; |
---|
2559 | |
---|
2560 | *_os << '\t' << '\t'; |
---|
2561 | - if (_write_label) { |
---|
2562 | + if (label == 0) { |
---|
2563 | *_os << "label" << '\t'; |
---|
2564 | } |
---|
2565 | for (typename ArcMaps::iterator it = _arc_maps.begin(); |
---|
2566 | @@ -467,14 +511,28 @@ namespace lemon { |
---|
2567 | } |
---|
2568 | *_os << std::endl; |
---|
2569 | |
---|
2570 | - for (ArcIt a(_digraph); a != INVALID; ++a) { |
---|
2571 | + std::vector<Arc> arcs; |
---|
2572 | + for (ArcIt n(_digraph); n != INVALID; ++n) { |
---|
2573 | + arcs.push_back(n); |
---|
2574 | + } |
---|
2575 | + |
---|
2576 | + if (label == 0) { |
---|
2577 | + IdMap<Digraph, Arc> id_map(_digraph); |
---|
2578 | + _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map); |
---|
2579 | + std::sort(arcs.begin(), arcs.end(), id_less); |
---|
2580 | + } else { |
---|
2581 | + label->sort(arcs); |
---|
2582 | + } |
---|
2583 | + |
---|
2584 | + for (int i = 0; i < static_cast<int>(arcs.size()); ++i) { |
---|
2585 | + Arc a = arcs[i]; |
---|
2586 | _writer_bits::writeToken(*_os, _node_index. |
---|
2587 | find(_digraph.source(a))->second); |
---|
2588 | *_os << '\t'; |
---|
2589 | _writer_bits::writeToken(*_os, _node_index. |
---|
2590 | find(_digraph.target(a))->second); |
---|
2591 | *_os << '\t'; |
---|
2592 | - if (_write_label) { |
---|
2593 | + if (label == 0) { |
---|
2594 | std::ostringstream os; |
---|
2595 | os << _digraph.id(a); |
---|
2596 | _writer_bits::writeToken(*_os, os.str()); |
---|
2597 | # HG changeset patch |
---|
2598 | # User Balazs Dezso <deba@inf.elte.hu> |
---|
2599 | # Date 1207908422 -7200 |
---|
2600 | # Node ID 676fb304b549e57446844f189efcdffd3f78bffa |
---|
2601 | # Parent 80086ce5c586577faaa0dba778d0ecbd4c5450ad |
---|
2602 | Bug fix with attributes |
---|
2603 | |
---|
2604 | diff -r 80086ce5c586 -r 676fb304b549 demo/lgf_demo.cc |
---|
2605 | --- a/demo/lgf_demo.cc Fri Apr 11 11:37:19 2008 +0200 |
---|
2606 | +++ b/demo/lgf_demo.cc Fri Apr 11 12:07:02 2008 +0200 |
---|
2607 | @@ -47,6 +47,7 @@ int main(int argc, const char *argv[]) { |
---|
2608 | typedef Digraph::Arc Arc; |
---|
2609 | typedef Digraph::ArcIt ArcIt; |
---|
2610 | |
---|
2611 | + typedef Digraph::NodeMap<int> PotentialMap; |
---|
2612 | typedef Digraph::ArcMap<int> CapacityMap; |
---|
2613 | typedef Digraph::ArcMap<std::string> NameMap; |
---|
2614 | |
---|
2615 | @@ -55,14 +56,18 @@ int main(int argc, const char *argv[]) { |
---|
2616 | const int m = argc > 3 ? std::atoi(argv[3]) : 100; |
---|
2617 | |
---|
2618 | Digraph digraph; |
---|
2619 | + PotentialMap potential(digraph); |
---|
2620 | CapacityMap capacity(digraph); |
---|
2621 | NameMap name(digraph); |
---|
2622 | |
---|
2623 | std::vector<Node> nodes; |
---|
2624 | + for (int i = 0; i < n; ++i) { |
---|
2625 | + Node node = digraph.addNode(); |
---|
2626 | + potential[node] = rnd[m]; |
---|
2627 | + nodes.push_back(node); |
---|
2628 | + } |
---|
2629 | |
---|
2630 | - for (int i = 0; i < n; ++i) { |
---|
2631 | - nodes.push_back(digraph.addNode()); |
---|
2632 | - } |
---|
2633 | + std::vector<Arc> arcs; |
---|
2634 | for (int i = 0; i < e; ++i) { |
---|
2635 | int s = rnd[n]; |
---|
2636 | int t = rnd[n]; |
---|
2637 | @@ -72,14 +77,18 @@ int main(int argc, const char *argv[]) { |
---|
2638 | std::ostringstream os; |
---|
2639 | os << "arc \t" << i << std::endl; |
---|
2640 | name[arc] = os.str(); |
---|
2641 | + arcs.push_back(arc); |
---|
2642 | } |
---|
2643 | |
---|
2644 | |
---|
2645 | DigraphWriter<Digraph>(ss, digraph). |
---|
2646 | + nodeMap("potential", potential). |
---|
2647 | arcMap("capacity", capacity). |
---|
2648 | arcMap("name", name). |
---|
2649 | node("source", nodes[0]). |
---|
2650 | node("target", nodes[1]). |
---|
2651 | + arc("bottleneck", arcs[e / 2]). |
---|
2652 | + attribute("creator", "lemon library"). |
---|
2653 | run(); |
---|
2654 | |
---|
2655 | } catch (DataFormatError& error) { |
---|
2656 | @@ -93,27 +102,38 @@ int main(int argc, const char *argv[]) { |
---|
2657 | typedef Digraph::Arc Arc; |
---|
2658 | typedef Digraph::ArcIt ArcIt; |
---|
2659 | |
---|
2660 | + typedef Digraph::NodeMap<int> PotentialMap; |
---|
2661 | typedef Digraph::ArcMap<int> CapacityMap; |
---|
2662 | typedef Digraph::ArcMap<std::string> NameMap; |
---|
2663 | |
---|
2664 | Digraph digraph; |
---|
2665 | + PotentialMap potential(digraph); |
---|
2666 | CapacityMap capacity(digraph); |
---|
2667 | NameMap name(digraph); |
---|
2668 | |
---|
2669 | Node s, t; |
---|
2670 | + Arc a; |
---|
2671 | + |
---|
2672 | + std::string creator; |
---|
2673 | |
---|
2674 | DigraphReader<Digraph>(ss, digraph). |
---|
2675 | + nodeMap("potential", potential). |
---|
2676 | arcMap("capacity", capacity). |
---|
2677 | arcMap("name", name). |
---|
2678 | node("source", s). |
---|
2679 | node("target", t). |
---|
2680 | + arc("bottleneck", a). |
---|
2681 | + attribute("creator", creator). |
---|
2682 | run(); |
---|
2683 | |
---|
2684 | DigraphWriter<Digraph>(std::cout, digraph). |
---|
2685 | + nodeMap("potential", potential). |
---|
2686 | arcMap("capacity", capacity). |
---|
2687 | arcMap("name", name). |
---|
2688 | node("source", s). |
---|
2689 | node("target", t). |
---|
2690 | + arc("bottleneck", a). |
---|
2691 | + attribute("creator", creator). |
---|
2692 | run(); |
---|
2693 | |
---|
2694 | } catch (DataFormatError& error) { |
---|
2695 | diff -r 80086ce5c586 -r 676fb304b549 lemon/lgf_reader.h |
---|
2696 | --- a/lemon/lgf_reader.h Fri Apr 11 11:37:19 2008 +0200 |
---|
2697 | +++ b/lemon/lgf_reader.h Fri Apr 11 12:07:02 2008 +0200 |
---|
2698 | @@ -658,7 +658,10 @@ namespace lemon { |
---|
2699 | |
---|
2700 | std::string attr, token; |
---|
2701 | line >> attr; |
---|
2702 | - std::getline(line >> std::ws, token); |
---|
2703 | + _reader_bits::readToken(line, token); |
---|
2704 | + if (line >> c) { |
---|
2705 | + throw DataFormatError("Extra character on the end of line"); |
---|
2706 | + } |
---|
2707 | |
---|
2708 | typename Attributes::iterator it = _attributes.lower_bound(attr); |
---|
2709 | while (it != _attributes.end() && it->first == attr) { |
---|
2710 | # HG changeset patch |
---|
2711 | # User Balazs Dezso <deba@inf.elte.hu> |
---|
2712 | # Date 1207924771 -7200 |
---|
2713 | # Node ID b553a184f119055b4e6c4e8462363fc461fa5f1c |
---|
2714 | # Parent 676fb304b549e57446844f189efcdffd3f78bffa |
---|
2715 | Checking map concepts |
---|
2716 | |
---|
2717 | diff -r 676fb304b549 -r b553a184f119 lemon/lgf_reader.h |
---|
2718 | --- a/lemon/lgf_reader.h Fri Apr 11 12:07:02 2008 +0200 |
---|
2719 | +++ b/lemon/lgf_reader.h Fri Apr 11 16:39:31 2008 +0200 |
---|
2720 | @@ -33,6 +33,9 @@ |
---|
2721 | |
---|
2722 | #include <lemon/assert.h> |
---|
2723 | #include <lemon/graph_utils.h> |
---|
2724 | + |
---|
2725 | +#include <lemon/concept_check.h> |
---|
2726 | +#include <lemon/concepts/maps.h> |
---|
2727 | |
---|
2728 | namespace lemon { |
---|
2729 | |
---|
2730 | @@ -371,6 +374,7 @@ namespace lemon { |
---|
2731 | /// \e |
---|
2732 | template <typename Map> |
---|
2733 | DigraphReader& nodeMap(const std::string& caption, Map& map) { |
---|
2734 | + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
---|
2735 | _reader_bits::MapStorageBase<Node>* storage = |
---|
2736 | new _reader_bits::MapStorage<Node, Map>(map); |
---|
2737 | _node_maps.insert(std::make_pair(caption, storage)); |
---|
2738 | @@ -381,6 +385,7 @@ namespace lemon { |
---|
2739 | template <typename Map, typename Converter> |
---|
2740 | DigraphReader& nodeMap(const std::string& caption, Map& map, |
---|
2741 | const Converter& converter = Converter()) { |
---|
2742 | + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
---|
2743 | _reader_bits::MapStorageBase<Node>* storage = |
---|
2744 | new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
---|
2745 | _node_maps.insert(std::make_pair(caption, storage)); |
---|
2746 | @@ -390,6 +395,7 @@ namespace lemon { |
---|
2747 | /// \e |
---|
2748 | template <typename Map> |
---|
2749 | DigraphReader& arcMap(const std::string& caption, Map& map) { |
---|
2750 | + checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); |
---|
2751 | _reader_bits::MapStorageBase<Arc>* storage = |
---|
2752 | new _reader_bits::MapStorage<Arc, Map>(map); |
---|
2753 | _arc_maps.insert(std::make_pair(caption, storage)); |
---|
2754 | @@ -400,6 +406,7 @@ namespace lemon { |
---|
2755 | template <typename Map, typename Converter> |
---|
2756 | DigraphReader& arcMap(const std::string& caption, Map& map, |
---|
2757 | const Converter& converter = Converter()) { |
---|
2758 | + checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); |
---|
2759 | _reader_bits::MapStorageBase<Arc>* storage = |
---|
2760 | new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter); |
---|
2761 | _arc_maps.insert(std::make_pair(caption, storage)); |
---|
2762 | diff -r 676fb304b549 -r b553a184f119 lemon/lgf_writer.h |
---|
2763 | --- a/lemon/lgf_writer.h Fri Apr 11 12:07:02 2008 +0200 |
---|
2764 | +++ b/lemon/lgf_writer.h Fri Apr 11 16:39:31 2008 +0200 |
---|
2765 | @@ -331,6 +331,7 @@ namespace lemon { |
---|
2766 | /// \e |
---|
2767 | template <typename Map> |
---|
2768 | DigraphWriter& nodeMap(const std::string& caption, const Map& map) { |
---|
2769 | + checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
---|
2770 | _writer_bits::MapStorageBase<Node>* storage = |
---|
2771 | new _writer_bits::MapStorage<Node, Map>(map); |
---|
2772 | _node_maps.push_back(std::make_pair(caption, storage)); |
---|
2773 | @@ -341,6 +342,7 @@ namespace lemon { |
---|
2774 | template <typename Map, typename Converter> |
---|
2775 | DigraphWriter& nodeMap(const std::string& caption, const Map& map, |
---|
2776 | const Converter& converter = Converter()) { |
---|
2777 | + checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
---|
2778 | _writer_bits::MapStorageBase<Node>* storage = |
---|
2779 | new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); |
---|
2780 | _node_maps.push_back(std::make_pair(caption, storage)); |
---|
2781 | @@ -350,6 +352,7 @@ namespace lemon { |
---|
2782 | /// \e |
---|
2783 | template <typename Map> |
---|
2784 | DigraphWriter& arcMap(const std::string& caption, const Map& map) { |
---|
2785 | + checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); |
---|
2786 | _writer_bits::MapStorageBase<Arc>* storage = |
---|
2787 | new _writer_bits::MapStorage<Arc, Map>(map); |
---|
2788 | _arc_maps.push_back(std::make_pair(caption, storage)); |
---|
2789 | @@ -360,6 +363,7 @@ namespace lemon { |
---|
2790 | template <typename Map, typename Converter> |
---|
2791 | DigraphWriter& arcMap(const std::string& caption, const Map& map, |
---|
2792 | const Converter& converter = Converter()) { |
---|
2793 | + checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); |
---|
2794 | _writer_bits::MapStorageBase<Arc>* storage = |
---|
2795 | new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter); |
---|
2796 | _arc_maps.push_back(std::make_pair(caption, storage)); |
---|