gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 4 0
merge default
0 files changed with 211 insertions and 161 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\ingroup lemon_io
20 20
///\file
21 21
///\brief \ref lgf-format "LEMON Graph Format" reader.
22 22

	
23 23

	
24 24
#ifndef LEMON_LGF_READER_H
25 25
#define LEMON_LGF_READER_H
26 26

	
27 27
#include <iostream>
28 28
#include <fstream>
29 29
#include <sstream>
30 30

	
31 31
#include <set>
32 32
#include <map>
33 33

	
34 34
#include <lemon/core.h>
35 35

	
36 36
#include <lemon/lgf_writer.h>
37 37

	
38 38
#include <lemon/concept_check.h>
39 39
#include <lemon/concepts/maps.h>
40 40

	
41 41
namespace lemon {
42 42

	
43 43
  namespace _reader_bits {
44 44

	
45 45
    template <typename Value>
46 46
    struct DefaultConverter {
47 47
      Value operator()(const std::string& str) {
48 48
        std::istringstream is(str);
49 49
        Value value;
50 50
        if (!(is >> value)) {
51 51
          throw FormatError("Cannot read token");
52 52
        }
53 53

	
54 54
        char c;
55 55
        if (is >> std::ws >> c) {
56 56
          throw FormatError("Remaining characters in token");
57 57
        }
58 58
        return value;
59 59
      }
60 60
    };
61 61

	
62 62
    template <>
63 63
    struct DefaultConverter<std::string> {
64 64
      std::string operator()(const std::string& str) {
65 65
        return str;
66 66
      }
67 67
    };
68 68

	
69 69
    template <typename _Item>
70 70
    class MapStorageBase {
71 71
    public:
72 72
      typedef _Item Item;
73 73

	
74 74
    public:
75 75
      MapStorageBase() {}
76 76
      virtual ~MapStorageBase() {}
77 77

	
78 78
      virtual void set(const Item& item, const std::string& value) = 0;
79 79

	
80 80
    };
81 81

	
82 82
    template <typename _Item, typename _Map,
83 83
              typename _Converter = DefaultConverter<typename _Map::Value> >
84 84
    class MapStorage : public MapStorageBase<_Item> {
85 85
    public:
86 86
      typedef _Map Map;
87 87
      typedef _Converter Converter;
88 88
      typedef _Item Item;
89 89

	
90 90
    private:
91 91
      Map& _map;
92 92
      Converter _converter;
93 93

	
94 94
    public:
95 95
      MapStorage(Map& map, const Converter& converter = Converter())
96 96
        : _map(map), _converter(converter) {}
97 97
      virtual ~MapStorage() {}
98 98

	
99 99
      virtual void set(const Item& item ,const std::string& value) {
100 100
        _map.set(item, _converter(value));
101 101
      }
102 102
    };
103 103

	
104 104
    template <typename _Graph, bool _dir, typename _Map,
105 105
              typename _Converter = DefaultConverter<typename _Map::Value> >
106 106
    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
107 107
    public:
108 108
      typedef _Map Map;
109 109
      typedef _Converter Converter;
110 110
      typedef _Graph Graph;
111 111
      typedef typename Graph::Edge Item;
112 112
      static const bool dir = _dir;
113 113

	
114 114
    private:
115 115
      const Graph& _graph;
116 116
      Map& _map;
117 117
      Converter _converter;
118 118

	
119 119
    public:
120 120
      GraphArcMapStorage(const Graph& graph, Map& map,
121 121
                         const Converter& converter = Converter())
122 122
        : _graph(graph), _map(map), _converter(converter) {}
123 123
      virtual ~GraphArcMapStorage() {}
124 124

	
125 125
      virtual void set(const Item& item ,const std::string& value) {
126 126
        _map.set(_graph.direct(item, dir), _converter(value));
127 127
      }
128 128
    };
129 129

	
130 130
    class ValueStorageBase {
131 131
    public:
132 132
      ValueStorageBase() {}
133 133
      virtual ~ValueStorageBase() {}
134 134

	
135 135
      virtual void set(const std::string&) = 0;
136 136
    };
137 137

	
138 138
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
139 139
    class ValueStorage : public ValueStorageBase {
140 140
    public:
141 141
      typedef _Value Value;
142 142
      typedef _Converter Converter;
143 143

	
144 144
    private:
145 145
      Value& _value;
146 146
      Converter _converter;
147 147

	
148 148
    public:
149 149
      ValueStorage(Value& value, const Converter& converter = Converter())
150 150
        : _value(value), _converter(converter) {}
151 151

	
152 152
      virtual void set(const std::string& value) {
153 153
        _value = _converter(value);
154 154
      }
155 155
    };
156 156

	
157 157
    template <typename Value>
158 158
    struct MapLookUpConverter {
159 159
      const std::map<std::string, Value>& _map;
160 160

	
161 161
      MapLookUpConverter(const std::map<std::string, Value>& map)
162 162
        : _map(map) {}
163 163

	
164 164
      Value operator()(const std::string& str) {
165 165
        typename std::map<std::string, Value>::const_iterator it =
166 166
          _map.find(str);
167 167
        if (it == _map.end()) {
168 168
          std::ostringstream msg;
169 169
          msg << "Item not found: " << str;
170 170
          throw FormatError(msg.str());
171 171
        }
172 172
        return it->second;
173 173
      }
174 174
    };
175 175

	
176 176
    template <typename Graph>
177 177
    struct GraphArcLookUpConverter {
178 178
      const Graph& _graph;
179 179
      const std::map<std::string, typename Graph::Edge>& _map;
180 180

	
181 181
      GraphArcLookUpConverter(const Graph& graph,
182 182
                              const std::map<std::string,
183 183
                                             typename Graph::Edge>& map)
184 184
        : _graph(graph), _map(map) {}
185 185

	
186 186
      typename Graph::Arc operator()(const std::string& str) {
187 187
        if (str.empty() || (str[0] != '+' && str[0] != '-')) {
188 188
          throw FormatError("Item must start with '+' or '-'");
189 189
        }
190 190
        typename std::map<std::string, typename Graph::Edge>
191 191
          ::const_iterator it = _map.find(str.substr(1));
192 192
        if (it == _map.end()) {
193 193
          throw FormatError("Item not found");
194 194
        }
195 195
        return _graph.direct(it->second, str[0] == '+');
196 196
      }
197 197
    };
198 198

	
199 199
    inline bool isWhiteSpace(char c) {
200 200
      return c == ' ' || c == '\t' || c == '\v' ||
201 201
        c == '\n' || c == '\r' || c == '\f';
202 202
    }
203 203

	
204 204
    inline bool isOct(char c) {
205 205
      return '0' <= c && c <='7';
206 206
    }
207 207

	
208 208
    inline int valueOct(char c) {
209 209
      LEMON_ASSERT(isOct(c), "The character is not octal.");
210 210
      return c - '0';
211 211
    }
212 212

	
213 213
    inline bool isHex(char c) {
214 214
      return ('0' <= c && c <= '9') ||
215 215
        ('a' <= c && c <= 'z') ||
216 216
        ('A' <= c && c <= 'Z');
217 217
    }
218 218

	
219 219
    inline int valueHex(char c) {
220 220
      LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
221 221
      if ('0' <= c && c <= '9') return c - '0';
222 222
      if ('a' <= c && c <= 'z') return c - 'a' + 10;
223 223
      return c - 'A' + 10;
224 224
    }
225 225

	
226 226
    inline bool isIdentifierFirstChar(char c) {
227 227
      return ('a' <= c && c <= 'z') ||
228 228
        ('A' <= c && c <= 'Z') || c == '_';
229 229
    }
230 230

	
231 231
    inline bool isIdentifierChar(char c) {
232 232
      return isIdentifierFirstChar(c) ||
233 233
        ('0' <= c && c <= '9');
234 234
    }
235 235

	
236 236
    inline char readEscape(std::istream& is) {
237 237
      char c;
238 238
      if (!is.get(c))
239 239
        throw FormatError("Escape format error");
240 240

	
241 241
      switch (c) {
242 242
      case '\\':
243 243
        return '\\';
244 244
      case '\"':
245 245
        return '\"';
246 246
      case '\'':
247 247
        return '\'';
248 248
      case '\?':
249 249
        return '\?';
250 250
      case 'a':
251 251
        return '\a';
252 252
      case 'b':
253 253
        return '\b';
254 254
      case 'f':
255 255
        return '\f';
256 256
      case 'n':
257 257
        return '\n';
258 258
      case 'r':
259 259
        return '\r';
260 260
      case 't':
261 261
        return '\t';
262 262
      case 'v':
263 263
        return '\v';
264 264
      case 'x':
265 265
        {
266 266
          int code;
267 267
          if (!is.get(c) || !isHex(c))
268 268
            throw FormatError("Escape format error");
269 269
          else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
270 270
          else code = code * 16 + valueHex(c);
271 271
          return code;
272 272
        }
273 273
      default:
274 274
        {
275 275
          int code;
276 276
          if (!isOct(c))
277 277
            throw FormatError("Escape format error");
278 278
          else if (code = valueOct(c), !is.get(c) || !isOct(c))
279 279
            is.putback(c);
280 280
          else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
281 281
            is.putback(c);
282 282
          else code = code * 8 + valueOct(c);
283 283
          return code;
284 284
        }
285 285
      }
286 286
    }
287 287

	
288 288
    inline std::istream& readToken(std::istream& is, std::string& str) {
289 289
      std::ostringstream os;
290 290

	
291 291
      char c;
292 292
      is >> std::ws;
293 293

	
294 294
      if (!is.get(c))
295 295
        return is;
296 296

	
297 297
      if (c == '\"') {
298 298
        while (is.get(c) && c != '\"') {
299 299
          if (c == '\\')
300 300
            c = readEscape(is);
301 301
          os << c;
302 302
        }
303 303
        if (!is)
304 304
          throw FormatError("Quoted format error");
305 305
      } else {
306 306
        is.putback(c);
307 307
        while (is.get(c) && !isWhiteSpace(c)) {
308 308
          if (c == '\\')
309 309
            c = readEscape(is);
310 310
          os << c;
311 311
        }
312 312
        if (!is) {
313 313
          is.clear();
314 314
        } else {
315 315
          is.putback(c);
316 316
        }
317 317
      }
318 318
      str = os.str();
319 319
      return is;
320 320
    }
321 321

	
322 322
    class Section {
323 323
    public:
324 324
      virtual ~Section() {}
325 325
      virtual void process(std::istream& is, int& line_num) = 0;
326 326
    };
327 327

	
328 328
    template <typename Functor>
329 329
    class LineSection : public Section {
330 330
    private:
331 331

	
332 332
      Functor _functor;
333 333

	
334 334
    public:
335 335

	
336 336
      LineSection(const Functor& functor) : _functor(functor) {}
337 337
      virtual ~LineSection() {}
338 338

	
339 339
      virtual void process(std::istream& is, int& line_num) {
340 340
        char c;
341 341
        std::string line;
342 342
        while (is.get(c) && c != '@') {
343 343
          if (c == '\n') {
344 344
            ++line_num;
345 345
          } else if (c == '#') {
346 346
            getline(is, line);
347 347
            ++line_num;
348 348
          } else if (!isWhiteSpace(c)) {
349 349
            is.putback(c);
350 350
            getline(is, line);
351 351
            _functor(line);
352 352
            ++line_num;
353 353
          }
354 354
        }
355 355
        if (is) is.putback(c);
356 356
        else if (is.eof()) is.clear();
357 357
      }
358 358
    };
359 359

	
360 360
    template <typename Functor>
361 361
    class StreamSection : public Section {
362 362
    private:
363 363

	
364 364
      Functor _functor;
365 365

	
366 366
    public:
367 367

	
368 368
      StreamSection(const Functor& functor) : _functor(functor) {}
369 369
      virtual ~StreamSection() {}
370 370

	
371 371
      virtual void process(std::istream& is, int& line_num) {
372 372
        _functor(is, line_num);
373 373
        char c;
374 374
        std::string line;
375 375
        while (is.get(c) && c != '@') {
376 376
          if (c == '\n') {
377 377
            ++line_num;
378 378
          } else if (!isWhiteSpace(c)) {
379 379
            getline(is, line);
380 380
            ++line_num;
381 381
          }
382 382
        }
383 383
        if (is) is.putback(c);
384 384
        else if (is.eof()) is.clear();
385 385
      }
386 386
    };
387 387

	
388 388
  }
389 389

	
390 390
  template <typename Digraph>
391 391
  class DigraphReader;
392 392

	
393
  /// \brief Return a \ref DigraphReader class
394
  ///
395
  /// This function just returns a \ref DigraphReader class.
396
  /// \relates DigraphReader
397 393
  template <typename Digraph>
398
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
399
                                       std::istream& is = std::cin) {
400
    DigraphReader<Digraph> tmp(digraph, is);
401
    return tmp;
402
  }
403

	
404
  /// \brief Return a \ref DigraphReader class
405
  ///
406
  /// This function just returns a \ref DigraphReader class.
407
  /// \relates DigraphReader
394
  DigraphReader<Digraph> digraphReader(Digraph& digraph, 
395
                                       std::istream& is = std::cin);
408 396
  template <typename Digraph>
409
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
410
                                       const std::string& fn) {
411
    DigraphReader<Digraph> tmp(digraph, fn);
412
    return tmp;
413
  }
414

	
415
  /// \brief Return a \ref DigraphReader class
416
  ///
417
  /// This function just returns a \ref DigraphReader class.
418
  /// \relates DigraphReader
397
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const std::string& fn);
419 398
  template <typename Digraph>
420
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
421
    DigraphReader<Digraph> tmp(digraph, fn);
422
    return tmp;
423
  }
399
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char *fn);
424 400

	
425 401
  /// \ingroup lemon_io
426 402
  ///
427 403
  /// \brief \ref lgf-format "LGF" reader for directed graphs
428 404
  ///
429 405
  /// This utility reads an \ref lgf-format "LGF" file.
430 406
  ///
431 407
  /// The reading method does a batch processing. The user creates a
432 408
  /// reader object, then various reading rules can be added to the
433 409
  /// reader, and eventually the reading is executed with the \c run()
434 410
  /// member function. A map reading rule can be added to the reader
435 411
  /// with the \c nodeMap() or \c arcMap() members. An optional
436 412
  /// converter parameter can also be added as a standard functor
437 413
  /// converting from \c std::string to the value type of the map. If it
438 414
  /// is set, it will determine how the tokens in the file should be
439 415
  /// converted to the value type of the map. If the functor is not set,
440 416
  /// then a default conversion will be used. One map can be read into
441 417
  /// multiple map objects at the same time. The \c attribute(), \c
442 418
  /// node() and \c arc() functions are used to add attribute reading
443 419
  /// rules.
444 420
  ///
445 421
  ///\code
446 422
  /// DigraphReader<Digraph>(digraph, std::cin).
447 423
  ///   nodeMap("coordinates", coord_map).
448 424
  ///   arcMap("capacity", cap_map).
449 425
  ///   node("source", src).
450 426
  ///   node("target", trg).
451 427
  ///   attribute("caption", caption).
452 428
  ///   run();
453 429
  ///\endcode
454 430
  ///
455 431
  /// By default the reader uses the first section in the file of the
456 432
  /// proper type. If a section has an optional name, then it can be
457 433
  /// selected for reading by giving an optional name parameter to the
458 434
  /// \c nodes(), \c arcs() or \c attributes() functions.
459 435
  ///
460 436
  /// The \c useNodes() and \c useArcs() functions are used to tell the reader
461 437
  /// that the nodes or arcs should not be constructed (added to the
462 438
  /// graph) during the reading, but instead the label map of the items
463 439
  /// are given as a parameter of these functions. An
464 440
  /// application of these functions is multipass reading, which is
465 441
  /// important if two \c \@arcs sections must be read from the
466 442
  /// file. In this case the first phase would read the node set and one
467 443
  /// of the arc sets, while the second phase would read the second arc
468 444
  /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
469 445
  /// The previously read label node map should be passed to the \c
470 446
  /// useNodes() functions. Another application of multipass reading when
471 447
  /// paths are given as a node map or an arc map.
472 448
  /// It is impossible to read this in
473 449
  /// a single pass, because the arcs are not constructed when the node
474 450
  /// maps are read.
475 451
  template <typename _Digraph>
476 452
  class DigraphReader {
477 453
  public:
478 454

	
479 455
    typedef _Digraph Digraph;
480 456
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
481 457

	
482 458
  private:
483 459

	
484 460

	
485 461
    std::istream* _is;
486 462
    bool local_is;
487 463
    std::string _filename;
488 464

	
489 465
    Digraph& _digraph;
490 466

	
491 467
    std::string _nodes_caption;
492 468
    std::string _arcs_caption;
493 469
    std::string _attributes_caption;
494 470

	
495 471
    typedef std::map<std::string, Node> NodeIndex;
496 472
    NodeIndex _node_index;
497 473
    typedef std::map<std::string, Arc> ArcIndex;
498 474
    ArcIndex _arc_index;
499 475

	
500 476
    typedef std::vector<std::pair<std::string,
501 477
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
502 478
    NodeMaps _node_maps;
503 479

	
504 480
    typedef std::vector<std::pair<std::string,
505 481
      _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
506 482
    ArcMaps _arc_maps;
507 483

	
508 484
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
509 485
      Attributes;
510 486
    Attributes _attributes;
511 487

	
512 488
    bool _use_nodes;
513 489
    bool _use_arcs;
514 490

	
515 491
    bool _skip_nodes;
516 492
    bool _skip_arcs;
517 493

	
518 494
    int line_num;
519 495
    std::istringstream line;
520 496

	
521 497
  public:
522 498

	
523 499
    /// \brief Constructor
524 500
    ///
525 501
    /// Construct a directed graph reader, which reads from the given
526 502
    /// input stream.
527 503
    DigraphReader(Digraph& digraph, std::istream& is = std::cin)
528 504
      : _is(&is), local_is(false), _digraph(digraph),
529 505
        _use_nodes(false), _use_arcs(false),
530 506
        _skip_nodes(false), _skip_arcs(false) {}
531 507

	
532 508
    /// \brief Constructor
533 509
    ///
534 510
    /// Construct a directed graph reader, which reads from the given
535 511
    /// file.
536 512
    DigraphReader(Digraph& digraph, const std::string& fn)
537 513
      : _is(new std::ifstream(fn.c_str())), local_is(true),
538 514
        _filename(fn), _digraph(digraph),
539 515
        _use_nodes(false), _use_arcs(false),
540 516
        _skip_nodes(false), _skip_arcs(false) {
541 517
      if (!(*_is)) {
542 518
        delete _is;
543 519
        throw IoError("Cannot open file", fn);
544 520
      }
545 521
    }
546 522

	
547 523
    /// \brief Constructor
548 524
    ///
549 525
    /// Construct a directed graph reader, which reads from the given
550 526
    /// file.
551 527
    DigraphReader(Digraph& digraph, const char* fn)
552 528
      : _is(new std::ifstream(fn)), local_is(true),
553 529
        _filename(fn), _digraph(digraph),
554 530
        _use_nodes(false), _use_arcs(false),
555 531
        _skip_nodes(false), _skip_arcs(false) {
556 532
      if (!(*_is)) {
557 533
        delete _is;
558 534
        throw IoError("Cannot open file", fn);
559 535
      }
560 536
    }
561 537

	
562 538
    /// \brief Destructor
563 539
    ~DigraphReader() {
564 540
      for (typename NodeMaps::iterator it = _node_maps.begin();
565 541
           it != _node_maps.end(); ++it) {
566 542
        delete it->second;
567 543
      }
568 544

	
569 545
      for (typename ArcMaps::iterator it = _arc_maps.begin();
570 546
           it != _arc_maps.end(); ++it) {
571 547
        delete it->second;
572 548
      }
573 549

	
574 550
      for (typename Attributes::iterator it = _attributes.begin();
575 551
           it != _attributes.end(); ++it) {
576 552
        delete it->second;
577 553
      }
578 554

	
579 555
      if (local_is) {
580 556
        delete _is;
581 557
      }
582 558

	
583 559
    }
584 560

	
585 561
  private:
586 562

	
587
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
588
                                                  std::istream& is);
589
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
590
                                                  const std::string& fn);
591
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
592
                                                  const char *fn);
563
    template <typename DGR>
564
    friend DigraphReader<DGR> digraphReader(DGR& digraph, std::istream& is);
565
    template <typename DGR>
566
    friend DigraphReader<DGR> digraphReader(DGR& digraph, 
567
                                            const std::string& fn);
568
    template <typename DGR>
569
    friend DigraphReader<DGR> digraphReader(DGR& digraph, const char *fn);
593 570

	
594 571
    DigraphReader(DigraphReader& other)
595 572
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
596 573
        _use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
597 574
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
598 575

	
599 576
      other._is = 0;
600 577
      other.local_is = false;
601 578

	
602 579
      _node_index.swap(other._node_index);
603 580
      _arc_index.swap(other._arc_index);
604 581

	
605 582
      _node_maps.swap(other._node_maps);
606 583
      _arc_maps.swap(other._arc_maps);
607 584
      _attributes.swap(other._attributes);
608 585

	
609 586
      _nodes_caption = other._nodes_caption;
610 587
      _arcs_caption = other._arcs_caption;
611 588
      _attributes_caption = other._attributes_caption;
612 589

	
613 590
    }
614 591

	
615 592
    DigraphReader& operator=(const DigraphReader&);
616 593

	
617 594
  public:
618 595

	
619 596
    /// \name Reading rules
620 597
    /// @{
621 598

	
622 599
    /// \brief Node map reading rule
623 600
    ///
624 601
    /// Add a node map reading rule to the reader.
625 602
    template <typename Map>
626 603
    DigraphReader& nodeMap(const std::string& caption, Map& map) {
627 604
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
628 605
      _reader_bits::MapStorageBase<Node>* storage =
629 606
        new _reader_bits::MapStorage<Node, Map>(map);
630 607
      _node_maps.push_back(std::make_pair(caption, storage));
631 608
      return *this;
632 609
    }
633 610

	
634 611
    /// \brief Node map reading rule
635 612
    ///
636 613
    /// Add a node map reading rule with specialized converter to the
637 614
    /// reader.
638 615
    template <typename Map, typename Converter>
639 616
    DigraphReader& nodeMap(const std::string& caption, Map& map,
640 617
                           const Converter& converter = Converter()) {
641 618
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
642 619
      _reader_bits::MapStorageBase<Node>* storage =
643 620
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
644 621
      _node_maps.push_back(std::make_pair(caption, storage));
645 622
      return *this;
646 623
    }
647 624

	
648 625
    /// \brief Arc map reading rule
649 626
    ///
650 627
    /// Add an arc map reading rule to the reader.
651 628
    template <typename Map>
652 629
    DigraphReader& arcMap(const std::string& caption, Map& map) {
653 630
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
654 631
      _reader_bits::MapStorageBase<Arc>* storage =
655 632
        new _reader_bits::MapStorage<Arc, Map>(map);
656 633
      _arc_maps.push_back(std::make_pair(caption, storage));
657 634
      return *this;
658 635
    }
659 636

	
660 637
    /// \brief Arc map reading rule
661 638
    ///
662 639
    /// Add an arc map reading rule with specialized converter to the
663 640
    /// reader.
664 641
    template <typename Map, typename Converter>
665 642
    DigraphReader& arcMap(const std::string& caption, Map& map,
666 643
                          const Converter& converter = Converter()) {
667 644
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
668 645
      _reader_bits::MapStorageBase<Arc>* storage =
669 646
        new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
670 647
      _arc_maps.push_back(std::make_pair(caption, storage));
671 648
      return *this;
672 649
    }
673 650

	
674 651
    /// \brief Attribute reading rule
675 652
    ///
676 653
    /// Add an attribute reading rule to the reader.
677 654
    template <typename Value>
678 655
    DigraphReader& attribute(const std::string& caption, Value& value) {
679 656
      _reader_bits::ValueStorageBase* storage =
680 657
        new _reader_bits::ValueStorage<Value>(value);
681 658
      _attributes.insert(std::make_pair(caption, storage));
682 659
      return *this;
683 660
    }
684 661

	
685 662
    /// \brief Attribute reading rule
686 663
    ///
687 664
    /// Add an attribute reading rule with specialized converter to the
688 665
    /// reader.
689 666
    template <typename Value, typename Converter>
690 667
    DigraphReader& attribute(const std::string& caption, Value& value,
691 668
                             const Converter& converter = Converter()) {
692 669
      _reader_bits::ValueStorageBase* storage =
693 670
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
694 671
      _attributes.insert(std::make_pair(caption, storage));
695 672
      return *this;
696 673
    }
697 674

	
698 675
    /// \brief Node reading rule
699 676
    ///
700 677
    /// Add a node reading rule to reader.
701 678
    DigraphReader& node(const std::string& caption, Node& node) {
702 679
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
703 680
      Converter converter(_node_index);
704 681
      _reader_bits::ValueStorageBase* storage =
705 682
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
706 683
      _attributes.insert(std::make_pair(caption, storage));
707 684
      return *this;
708 685
    }
709 686

	
710 687
    /// \brief Arc reading rule
711 688
    ///
712 689
    /// Add an arc reading rule to reader.
713 690
    DigraphReader& arc(const std::string& caption, Arc& arc) {
714 691
      typedef _reader_bits::MapLookUpConverter<Arc> Converter;
715 692
      Converter converter(_arc_index);
716 693
      _reader_bits::ValueStorageBase* storage =
717 694
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
718 695
      _attributes.insert(std::make_pair(caption, storage));
719 696
      return *this;
720 697
    }
721 698

	
722 699
    /// @}
723 700

	
724 701
    /// \name Select section by name
725 702
    /// @{
726 703

	
727 704
    /// \brief Set \c \@nodes section to be read
728 705
    ///
729 706
    /// Set \c \@nodes section to be read
730 707
    DigraphReader& nodes(const std::string& caption) {
731 708
      _nodes_caption = caption;
732 709
      return *this;
733 710
    }
734 711

	
735 712
    /// \brief Set \c \@arcs section to be read
736 713
    ///
737 714
    /// Set \c \@arcs section to be read
738 715
    DigraphReader& arcs(const std::string& caption) {
739 716
      _arcs_caption = caption;
740 717
      return *this;
741 718
    }
742 719

	
743 720
    /// \brief Set \c \@attributes section to be read
744 721
    ///
745 722
    /// Set \c \@attributes section to be read
746 723
    DigraphReader& attributes(const std::string& caption) {
747 724
      _attributes_caption = caption;
748 725
      return *this;
749 726
    }
750 727

	
751 728
    /// @}
752 729

	
753 730
    /// \name Using previously constructed node or arc set
754 731
    /// @{
755 732

	
756 733
    /// \brief Use previously constructed node set
757 734
    ///
758 735
    /// Use previously constructed node set, and specify the node
759 736
    /// label map.
760 737
    template <typename Map>
761 738
    DigraphReader& useNodes(const Map& map) {
762 739
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
763 740
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
764 741
      _use_nodes = true;
765 742
      _writer_bits::DefaultConverter<typename Map::Value> converter;
766 743
      for (NodeIt n(_digraph); n != INVALID; ++n) {
767 744
        _node_index.insert(std::make_pair(converter(map[n]), n));
768 745
      }
769 746
      return *this;
770 747
    }
771 748

	
772 749
    /// \brief Use previously constructed node set
773 750
    ///
774 751
    /// Use previously constructed node set, and specify the node
775 752
    /// label map and a functor which converts the label map values to
776 753
    /// \c std::string.
777 754
    template <typename Map, typename Converter>
778 755
    DigraphReader& useNodes(const Map& map,
779 756
                            const Converter& converter = Converter()) {
780 757
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
781 758
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
782 759
      _use_nodes = true;
783 760
      for (NodeIt n(_digraph); n != INVALID; ++n) {
784 761
        _node_index.insert(std::make_pair(converter(map[n]), n));
785 762
      }
786 763
      return *this;
787 764
    }
788 765

	
789 766
    /// \brief Use previously constructed arc set
790 767
    ///
791 768
    /// Use previously constructed arc set, and specify the arc
792 769
    /// label map.
793 770
    template <typename Map>
794 771
    DigraphReader& useArcs(const Map& map) {
795 772
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
796 773
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
797 774
      _use_arcs = true;
798 775
      _writer_bits::DefaultConverter<typename Map::Value> converter;
799 776
      for (ArcIt a(_digraph); a != INVALID; ++a) {
800 777
        _arc_index.insert(std::make_pair(converter(map[a]), a));
801 778
      }
802 779
      return *this;
803 780
    }
804 781

	
805 782
    /// \brief Use previously constructed arc set
806 783
    ///
807 784
    /// Use previously constructed arc set, and specify the arc
808 785
    /// label map and a functor which converts the label map values to
809 786
    /// \c std::string.
810 787
    template <typename Map, typename Converter>
811 788
    DigraphReader& useArcs(const Map& map,
812 789
                           const Converter& converter = Converter()) {
813 790
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
814 791
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
815 792
      _use_arcs = true;
816 793
      for (ArcIt a(_digraph); a != INVALID; ++a) {
817 794
        _arc_index.insert(std::make_pair(converter(map[a]), a));
818 795
      }
819 796
      return *this;
820 797
    }
821 798

	
822 799
    /// \brief Skips the reading of node section
823 800
    ///
824 801
    /// Omit the reading of the node section. This implies that each node
825 802
    /// map reading rule will be abandoned, and the nodes of the graph
826 803
    /// will not be constructed, which usually cause that the arc set
827 804
    /// could not be read due to lack of node name resolving.
828 805
    /// Therefore \c skipArcs() function should also be used, or
829 806
    /// \c useNodes() should be used to specify the label of the nodes.
830 807
    DigraphReader& skipNodes() {
831 808
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
832 809
      _skip_nodes = true;
833 810
      return *this;
834 811
    }
835 812

	
836 813
    /// \brief Skips the reading of arc section
837 814
    ///
838 815
    /// Omit the reading of the arc section. This implies that each arc
839 816
    /// map reading rule will be abandoned, and the arcs of the graph
840 817
    /// will not be constructed.
841 818
    DigraphReader& skipArcs() {
842 819
      LEMON_ASSERT(!_skip_arcs, "Skip arcs already set");
843 820
      _skip_arcs = true;
844 821
      return *this;
845 822
    }
846 823

	
847 824
    /// @}
848 825

	
849 826
  private:
850 827

	
851 828
    bool readLine() {
852 829
      std::string str;
853 830
      while(++line_num, std::getline(*_is, str)) {
854 831
        line.clear(); line.str(str);
855 832
        char c;
856 833
        if (line >> std::ws >> c && c != '#') {
857 834
          line.putback(c);
858 835
          return true;
859 836
        }
860 837
      }
861 838
      return false;
862 839
    }
863 840

	
864 841
    bool readSuccess() {
865 842
      return static_cast<bool>(*_is);
866 843
    }
867 844

	
868 845
    void skipSection() {
869 846
      char c;
870 847
      while (readSuccess() && line >> c && c != '@') {
871 848
        readLine();
872 849
      }
873 850
      line.putback(c);
874 851
    }
875 852

	
876 853
    void readNodes() {
877 854

	
878 855
      std::vector<int> map_index(_node_maps.size());
879 856
      int map_num, label_index;
880 857

	
881 858
      char c;
882 859
      if (!readLine() || !(line >> c) || c == '@') {
883 860
        if (readSuccess() && line) line.putback(c);
884 861
        if (!_node_maps.empty())
885 862
          throw FormatError("Cannot find map names");
886 863
        return;
887 864
      }
888 865
      line.putback(c);
889 866

	
890 867
      {
891 868
        std::map<std::string, int> maps;
892 869

	
893 870
        std::string map;
894 871
        int index = 0;
895 872
        while (_reader_bits::readToken(line, map)) {
896 873
          if (maps.find(map) != maps.end()) {
897 874
            std::ostringstream msg;
898 875
            msg << "Multiple occurence of node map: " << map;
899 876
            throw FormatError(msg.str());
900 877
          }
901 878
          maps.insert(std::make_pair(map, index));
902 879
          ++index;
903 880
        }
904 881

	
905 882
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
906 883
          std::map<std::string, int>::iterator jt =
907 884
            maps.find(_node_maps[i].first);
908 885
          if (jt == maps.end()) {
909 886
            std::ostringstream msg;
910 887
            msg << "Map not found: " << _node_maps[i].first;
911 888
            throw FormatError(msg.str());
912 889
          }
913 890
          map_index[i] = jt->second;
914 891
        }
915 892

	
916 893
        {
917 894
          std::map<std::string, int>::iterator jt = maps.find("label");
918 895
          if (jt != maps.end()) {
919 896
            label_index = jt->second;
920 897
          } else {
921 898
            label_index = -1;
922 899
          }
923 900
        }
924 901
        map_num = maps.size();
925 902
      }
926 903

	
927 904
      while (readLine() && line >> c && c != '@') {
928 905
        line.putback(c);
929 906

	
930 907
        std::vector<std::string> tokens(map_num);
931 908
        for (int i = 0; i < map_num; ++i) {
932 909
          if (!_reader_bits::readToken(line, tokens[i])) {
933 910
            std::ostringstream msg;
934 911
            msg << "Column not found (" << i + 1 << ")";
935 912
            throw FormatError(msg.str());
936 913
          }
937 914
        }
938 915
        if (line >> std::ws >> c)
939 916
          throw FormatError("Extra character at the end of line");
940 917

	
941 918
        Node n;
942 919
        if (!_use_nodes) {
943 920
          n = _digraph.addNode();
944 921
          if (label_index != -1)
945 922
            _node_index.insert(std::make_pair(tokens[label_index], n));
946 923
        } else {
947 924
          if (label_index == -1)
948 925
            throw FormatError("Label map not found");
949 926
          typename std::map<std::string, Node>::iterator it =
950 927
            _node_index.find(tokens[label_index]);
951 928
          if (it == _node_index.end()) {
952 929
            std::ostringstream msg;
953 930
            msg << "Node with label not found: " << tokens[label_index];
954 931
            throw FormatError(msg.str());
955 932
          }
956 933
          n = it->second;
957 934
        }
958 935

	
959 936
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
960 937
          _node_maps[i].second->set(n, tokens[map_index[i]]);
961 938
        }
962 939

	
963 940
      }
964 941
      if (readSuccess()) {
965 942
        line.putback(c);
966 943
      }
967 944
    }
968 945

	
969 946
    void readArcs() {
970 947

	
971 948
      std::vector<int> map_index(_arc_maps.size());
972 949
      int map_num, label_index;
973 950

	
974 951
      char c;
975 952
      if (!readLine() || !(line >> c) || c == '@') {
976 953
        if (readSuccess() && line) line.putback(c);
977 954
        if (!_arc_maps.empty())
978 955
          throw FormatError("Cannot find map names");
979 956
        return;
980 957
      }
981 958
      line.putback(c);
982 959

	
983 960
      {
984 961
        std::map<std::string, int> maps;
985 962

	
986 963
        std::string map;
987 964
        int index = 0;
988 965
        while (_reader_bits::readToken(line, map)) {
989 966
          if (maps.find(map) != maps.end()) {
990 967
            std::ostringstream msg;
991 968
            msg << "Multiple occurence of arc map: " << map;
992 969
            throw FormatError(msg.str());
993 970
          }
994 971
          maps.insert(std::make_pair(map, index));
995 972
          ++index;
996 973
        }
997 974

	
998 975
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
999 976
          std::map<std::string, int>::iterator jt =
1000 977
            maps.find(_arc_maps[i].first);
1001 978
          if (jt == maps.end()) {
1002 979
            std::ostringstream msg;
1003 980
            msg << "Map not found: " << _arc_maps[i].first;
1004 981
            throw FormatError(msg.str());
1005 982
          }
1006 983
          map_index[i] = jt->second;
1007 984
        }
1008 985

	
1009 986
        {
1010 987
          std::map<std::string, int>::iterator jt = maps.find("label");
1011 988
          if (jt != maps.end()) {
1012 989
            label_index = jt->second;
1013 990
          } else {
1014 991
            label_index = -1;
1015 992
          }
1016 993
        }
1017 994
        map_num = maps.size();
1018 995
      }
1019 996

	
1020 997
      while (readLine() && line >> c && c != '@') {
1021 998
        line.putback(c);
1022 999

	
1023 1000
        std::string source_token;
1024 1001
        std::string target_token;
1025 1002

	
1026 1003
        if (!_reader_bits::readToken(line, source_token))
1027 1004
          throw FormatError("Source not found");
1028 1005

	
1029 1006
        if (!_reader_bits::readToken(line, target_token))
1030 1007
          throw FormatError("Target not found");
1031 1008

	
1032 1009
        std::vector<std::string> tokens(map_num);
1033 1010
        for (int i = 0; i < map_num; ++i) {
1034 1011
          if (!_reader_bits::readToken(line, tokens[i])) {
1035 1012
            std::ostringstream msg;
1036 1013
            msg << "Column not found (" << i + 1 << ")";
1037 1014
            throw FormatError(msg.str());
1038 1015
          }
1039 1016
        }
1040 1017
        if (line >> std::ws >> c)
1041 1018
          throw FormatError("Extra character at the end of line");
1042 1019

	
1043 1020
        Arc a;
1044 1021
        if (!_use_arcs) {
1045 1022

	
1046 1023
          typename NodeIndex::iterator it;
1047 1024

	
1048 1025
          it = _node_index.find(source_token);
1049 1026
          if (it == _node_index.end()) {
1050 1027
            std::ostringstream msg;
1051 1028
            msg << "Item not found: " << source_token;
1052 1029
            throw FormatError(msg.str());
1053 1030
          }
1054 1031
          Node source = it->second;
1055 1032

	
1056 1033
          it = _node_index.find(target_token);
1057 1034
          if (it == _node_index.end()) {
1058 1035
            std::ostringstream msg;
1059 1036
            msg << "Item not found: " << target_token;
1060 1037
            throw FormatError(msg.str());
1061 1038
          }
1062 1039
          Node target = it->second;
1063 1040

	
1064 1041
          a = _digraph.addArc(source, target);
1065 1042
          if (label_index != -1)
1066 1043
            _arc_index.insert(std::make_pair(tokens[label_index], a));
1067 1044
        } else {
1068 1045
          if (label_index == -1)
1069 1046
            throw FormatError("Label map not found");
1070 1047
          typename std::map<std::string, Arc>::iterator it =
1071 1048
            _arc_index.find(tokens[label_index]);
1072 1049
          if (it == _arc_index.end()) {
1073 1050
            std::ostringstream msg;
1074 1051
            msg << "Arc with label not found: " << tokens[label_index];
1075 1052
            throw FormatError(msg.str());
1076 1053
          }
1077 1054
          a = it->second;
1078 1055
        }
1079 1056

	
1080 1057
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1081 1058
          _arc_maps[i].second->set(a, tokens[map_index[i]]);
1082 1059
        }
1083 1060

	
1084 1061
      }
1085 1062
      if (readSuccess()) {
1086 1063
        line.putback(c);
1087 1064
      }
1088 1065
    }
1089 1066

	
1090 1067
    void readAttributes() {
1091 1068

	
1092 1069
      std::set<std::string> read_attr;
1093 1070

	
1094 1071
      char c;
1095 1072
      while (readLine() && line >> c && c != '@') {
1096 1073
        line.putback(c);
1097 1074

	
1098 1075
        std::string attr, token;
1099 1076
        if (!_reader_bits::readToken(line, attr))
1100 1077
          throw FormatError("Attribute name not found");
1101 1078
        if (!_reader_bits::readToken(line, token))
1102 1079
          throw FormatError("Attribute value not found");
1103 1080
        if (line >> c)
1104 1081
          throw FormatError("Extra character at the end of line");
1105 1082

	
1106 1083
        {
1107 1084
          std::set<std::string>::iterator it = read_attr.find(attr);
1108 1085
          if (it != read_attr.end()) {
1109 1086
            std::ostringstream msg;
1110 1087
            msg << "Multiple occurence of attribute: " << attr;
1111 1088
            throw FormatError(msg.str());
1112 1089
          }
1113 1090
          read_attr.insert(attr);
1114 1091
        }
1115 1092

	
1116 1093
        {
1117 1094
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1118 1095
          while (it != _attributes.end() && it->first == attr) {
1119 1096
            it->second->set(token);
1120 1097
            ++it;
1121 1098
          }
1122 1099
        }
1123 1100

	
1124 1101
      }
1125 1102
      if (readSuccess()) {
1126 1103
        line.putback(c);
1127 1104
      }
1128 1105
      for (typename Attributes::iterator it = _attributes.begin();
1129 1106
           it != _attributes.end(); ++it) {
1130 1107
        if (read_attr.find(it->first) == read_attr.end()) {
1131 1108
          std::ostringstream msg;
1132 1109
          msg << "Attribute not found: " << it->first;
1133 1110
          throw FormatError(msg.str());
1134 1111
        }
1135 1112
      }
1136 1113
    }
1137 1114

	
1138 1115
  public:
1139 1116

	
1140 1117
    /// \name Execution of the reader
1141 1118
    /// @{
1142 1119

	
1143 1120
    /// \brief Start the batch processing
1144 1121
    ///
1145 1122
    /// This function starts the batch processing
1146 1123
    void run() {
1147 1124
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1148 1125

	
1149 1126
      bool nodes_done = _skip_nodes;
1150 1127
      bool arcs_done = _skip_arcs;
1151 1128
      bool attributes_done = false;
1152 1129

	
1153 1130
      line_num = 0;
1154 1131
      readLine();
1155 1132
      skipSection();
1156 1133

	
1157 1134
      while (readSuccess()) {
1158 1135
        try {
1159 1136
          char c;
1160 1137
          std::string section, caption;
1161 1138
          line >> c;
1162 1139
          _reader_bits::readToken(line, section);
1163 1140
          _reader_bits::readToken(line, caption);
1164 1141

	
1165 1142
          if (line >> c)
1166 1143
            throw FormatError("Extra character at the end of line");
1167 1144

	
1168 1145
          if (section == "nodes" && !nodes_done) {
1169 1146
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1170 1147
              readNodes();
1171 1148
              nodes_done = true;
1172 1149
            }
1173 1150
          } else if ((section == "arcs" || section == "edges") &&
1174 1151
                     !arcs_done) {
1175 1152
            if (_arcs_caption.empty() || _arcs_caption == caption) {
1176 1153
              readArcs();
1177 1154
              arcs_done = true;
1178 1155
            }
1179 1156
          } else if (section == "attributes" && !attributes_done) {
1180 1157
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1181 1158
              readAttributes();
1182 1159
              attributes_done = true;
1183 1160
            }
1184 1161
          } else {
1185 1162
            readLine();
1186 1163
            skipSection();
1187 1164
          }
1188 1165
        } catch (FormatError& error) {
1189 1166
          error.line(line_num);
1190 1167
          error.file(_filename);
1191 1168
          throw;
1192 1169
        }
1193 1170
      }
1194 1171

	
1195 1172
      if (!nodes_done) {
1196 1173
        throw FormatError("Section @nodes not found");
1197 1174
      }
1198 1175

	
1199 1176
      if (!arcs_done) {
1200 1177
        throw FormatError("Section @arcs not found");
1201 1178
      }
1202 1179

	
1203 1180
      if (!attributes_done && !_attributes.empty()) {
1204 1181
        throw FormatError("Section @attributes not found");
1205 1182
      }
1206 1183

	
1207 1184
    }
1208 1185

	
1209 1186
    /// @}
1210 1187

	
1211 1188
  };
1212 1189

	
1190
  /// \brief Return a \ref DigraphReader class
1191
  ///
1192
  /// This function just returns a \ref DigraphReader class.
1193
  /// \relates DigraphReader
1194
  template <typename Digraph>
1195
  DigraphReader<Digraph> digraphReader(Digraph& digraph, std::istream& is) {
1196
    DigraphReader<Digraph> tmp(digraph, is);
1197
    return tmp;
1198
  }
1199

	
1200
  /// \brief Return a \ref DigraphReader class
1201
  ///
1202
  /// This function just returns a \ref DigraphReader class.
1203
  /// \relates DigraphReader
1204
  template <typename Digraph>
1205
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
1206
                                       const std::string& fn) {
1207
    DigraphReader<Digraph> tmp(digraph, fn);
1208
    return tmp;
1209
  }
1210

	
1211
  /// \brief Return a \ref DigraphReader class
1212
  ///
1213
  /// This function just returns a \ref DigraphReader class.
1214
  /// \relates DigraphReader
1215
  template <typename Digraph>
1216
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
1217
    DigraphReader<Digraph> tmp(digraph, fn);
1218
    return tmp;
1219
  }
1220

	
1213 1221
  template <typename Graph>
1214 1222
  class GraphReader;
1215

	
1216
  /// \brief Return a \ref GraphReader class
1217
  ///
1218
  /// This function just returns a \ref GraphReader class.
1219
  /// \relates GraphReader
1223
 
1220 1224
  template <typename Graph>
1221
  GraphReader<Graph> graphReader(Graph& graph, std::istream& is = std::cin) {
1222
    GraphReader<Graph> tmp(graph, is);
1223
    return tmp;
1224
  }
1225

	
1226
  /// \brief Return a \ref GraphReader class
1227
  ///
1228
  /// This function just returns a \ref GraphReader class.
1229
  /// \relates GraphReader
1225
  GraphReader<Graph> graphReader(Graph& graph, 
1226
                                 std::istream& is = std::cin);
1230 1227
  template <typename Graph>
1231
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
1232
    GraphReader<Graph> tmp(graph, fn);
1233
    return tmp;
1234
  }
1235

	
1236
  /// \brief Return a \ref GraphReader class
1237
  ///
1238
  /// This function just returns a \ref GraphReader class.
1239
  /// \relates GraphReader
1228
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
1240 1229
  template <typename Graph>
1241
  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
1242
    GraphReader<Graph> tmp(graph, fn);
1243
    return tmp;
1244
  }
1230
  GraphReader<Graph> graphReader(Graph& graph, const char *fn);
1245 1231

	
1246 1232
  /// \ingroup lemon_io
1247 1233
  ///
1248 1234
  /// \brief \ref lgf-format "LGF" reader for undirected graphs
1249 1235
  ///
1250 1236
  /// This utility reads an \ref lgf-format "LGF" file.
1251 1237
  ///
1252 1238
  /// It can be used almost the same way as \c DigraphReader.
1253 1239
  /// The only difference is that this class can handle edges and
1254 1240
  /// edge maps as well as arcs and arc maps.
1255 1241
  ///
1256 1242
  /// The columns in the \c \@edges (or \c \@arcs) section are the
1257 1243
  /// edge maps. However, if there are two maps with the same name
1258 1244
  /// prefixed with \c '+' and \c '-', then these can be read into an
1259 1245
  /// arc map.  Similarly, an attribute can be read into an arc, if
1260 1246
  /// it's value is an edge label prefixed with \c '+' or \c '-'.
1261 1247
  template <typename _Graph>
1262 1248
  class GraphReader {
1263 1249
  public:
1264 1250

	
1265 1251
    typedef _Graph Graph;
1266 1252
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1267 1253

	
1268 1254
  private:
1269 1255

	
1270 1256
    std::istream* _is;
1271 1257
    bool local_is;
1272 1258
    std::string _filename;
1273 1259

	
1274 1260
    Graph& _graph;
1275 1261

	
1276 1262
    std::string _nodes_caption;
1277 1263
    std::string _edges_caption;
1278 1264
    std::string _attributes_caption;
1279 1265

	
1280 1266
    typedef std::map<std::string, Node> NodeIndex;
1281 1267
    NodeIndex _node_index;
1282 1268
    typedef std::map<std::string, Edge> EdgeIndex;
1283 1269
    EdgeIndex _edge_index;
1284 1270

	
1285 1271
    typedef std::vector<std::pair<std::string,
1286 1272
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1287 1273
    NodeMaps _node_maps;
1288 1274

	
1289 1275
    typedef std::vector<std::pair<std::string,
1290 1276
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1291 1277
    EdgeMaps _edge_maps;
1292 1278

	
1293 1279
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1294 1280
      Attributes;
1295 1281
    Attributes _attributes;
1296 1282

	
1297 1283
    bool _use_nodes;
1298 1284
    bool _use_edges;
1299 1285

	
1300 1286
    bool _skip_nodes;
1301 1287
    bool _skip_edges;
1302 1288

	
1303 1289
    int line_num;
1304 1290
    std::istringstream line;
1305 1291

	
1306 1292
  public:
1307 1293

	
1308 1294
    /// \brief Constructor
1309 1295
    ///
1310 1296
    /// Construct an undirected graph reader, which reads from the given
1311 1297
    /// input stream.
1312 1298
    GraphReader(Graph& graph, std::istream& is = std::cin)
1313 1299
      : _is(&is), local_is(false), _graph(graph),
1314 1300
        _use_nodes(false), _use_edges(false),
1315 1301
        _skip_nodes(false), _skip_edges(false) {}
1316 1302

	
1317 1303
    /// \brief Constructor
1318 1304
    ///
1319 1305
    /// Construct an undirected graph reader, which reads from the given
1320 1306
    /// file.
1321 1307
    GraphReader(Graph& graph, const std::string& fn)
1322 1308
      : _is(new std::ifstream(fn.c_str())), local_is(true),
1323 1309
        _filename(fn), _graph(graph),
1324 1310
        _use_nodes(false), _use_edges(false),
1325 1311
        _skip_nodes(false), _skip_edges(false) {
1326 1312
      if (!(*_is)) {
1327 1313
        delete _is;
1328 1314
        throw IoError("Cannot open file", fn);
1329 1315
      }
1330 1316
    }
1331 1317

	
1332 1318
    /// \brief Constructor
1333 1319
    ///
1334 1320
    /// Construct an undirected graph reader, which reads from the given
1335 1321
    /// file.
1336 1322
    GraphReader(Graph& graph, const char* fn)
1337 1323
      : _is(new std::ifstream(fn)), local_is(true),
1338 1324
        _filename(fn), _graph(graph),
1339 1325
        _use_nodes(false), _use_edges(false),
1340 1326
        _skip_nodes(false), _skip_edges(false) {
1341 1327
      if (!(*_is)) {
1342 1328
        delete _is;
1343 1329
        throw IoError("Cannot open file", fn);
1344 1330
      }
1345 1331
    }
1346 1332

	
1347 1333
    /// \brief Destructor
1348 1334
    ~GraphReader() {
1349 1335
      for (typename NodeMaps::iterator it = _node_maps.begin();
1350 1336
           it != _node_maps.end(); ++it) {
1351 1337
        delete it->second;
1352 1338
      }
1353 1339

	
1354 1340
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1355 1341
           it != _edge_maps.end(); ++it) {
1356 1342
        delete it->second;
1357 1343
      }
1358 1344

	
1359 1345
      for (typename Attributes::iterator it = _attributes.begin();
1360 1346
           it != _attributes.end(); ++it) {
1361 1347
        delete it->second;
1362 1348
      }
1363 1349

	
1364 1350
      if (local_is) {
1365 1351
        delete _is;
1366 1352
      }
1367 1353

	
1368 1354
    }
1369 1355

	
1370 1356
  private:
1371
    friend GraphReader<Graph> graphReader<>(Graph& graph, std::istream& is);
1372
    friend GraphReader<Graph> graphReader<>(Graph& graph,
1373
                                            const std::string& fn);
1374
    friend GraphReader<Graph> graphReader<>(Graph& graph, const char *fn);
1357
    template <typename GR>
1358
    friend GraphReader<GR> graphReader(GR& graph, std::istream& is);
1359
    template <typename GR>
1360
    friend GraphReader<GR> graphReader(GR& graph, const std::string& fn); 
1361
    template <typename GR>
1362
    friend GraphReader<GR> graphReader(GR& graph, const char *fn);
1375 1363

	
1376 1364
    GraphReader(GraphReader& other)
1377 1365
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1378 1366
        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
1379 1367
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1380 1368

	
1381 1369
      other._is = 0;
1382 1370
      other.local_is = false;
1383 1371

	
1384 1372
      _node_index.swap(other._node_index);
1385 1373
      _edge_index.swap(other._edge_index);
1386 1374

	
1387 1375
      _node_maps.swap(other._node_maps);
1388 1376
      _edge_maps.swap(other._edge_maps);
1389 1377
      _attributes.swap(other._attributes);
1390 1378

	
1391 1379
      _nodes_caption = other._nodes_caption;
1392 1380
      _edges_caption = other._edges_caption;
1393 1381
      _attributes_caption = other._attributes_caption;
1394 1382

	
1395 1383
    }
1396 1384

	
1397 1385
    GraphReader& operator=(const GraphReader&);
1398 1386

	
1399 1387
  public:
1400 1388

	
1401 1389
    /// \name Reading rules
1402 1390
    /// @{
1403 1391

	
1404 1392
    /// \brief Node map reading rule
1405 1393
    ///
1406 1394
    /// Add a node map reading rule to the reader.
1407 1395
    template <typename Map>
1408 1396
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1409 1397
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1410 1398
      _reader_bits::MapStorageBase<Node>* storage =
1411 1399
        new _reader_bits::MapStorage<Node, Map>(map);
1412 1400
      _node_maps.push_back(std::make_pair(caption, storage));
1413 1401
      return *this;
1414 1402
    }
1415 1403

	
1416 1404
    /// \brief Node map reading rule
1417 1405
    ///
1418 1406
    /// Add a node map reading rule with specialized converter to the
1419 1407
    /// reader.
1420 1408
    template <typename Map, typename Converter>
1421 1409
    GraphReader& nodeMap(const std::string& caption, Map& map,
1422 1410
                           const Converter& converter = Converter()) {
1423 1411
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1424 1412
      _reader_bits::MapStorageBase<Node>* storage =
1425 1413
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1426 1414
      _node_maps.push_back(std::make_pair(caption, storage));
1427 1415
      return *this;
1428 1416
    }
1429 1417

	
1430 1418
    /// \brief Edge map reading rule
1431 1419
    ///
1432 1420
    /// Add an edge map reading rule to the reader.
1433 1421
    template <typename Map>
1434 1422
    GraphReader& edgeMap(const std::string& caption, Map& map) {
1435 1423
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1436 1424
      _reader_bits::MapStorageBase<Edge>* storage =
1437 1425
        new _reader_bits::MapStorage<Edge, Map>(map);
1438 1426
      _edge_maps.push_back(std::make_pair(caption, storage));
1439 1427
      return *this;
1440 1428
    }
1441 1429

	
1442 1430
    /// \brief Edge map reading rule
1443 1431
    ///
1444 1432
    /// Add an edge map reading rule with specialized converter to the
1445 1433
    /// reader.
1446 1434
    template <typename Map, typename Converter>
1447 1435
    GraphReader& edgeMap(const std::string& caption, Map& map,
1448 1436
                          const Converter& converter = Converter()) {
1449 1437
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1450 1438
      _reader_bits::MapStorageBase<Edge>* storage =
1451 1439
        new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1452 1440
      _edge_maps.push_back(std::make_pair(caption, storage));
1453 1441
      return *this;
1454 1442
    }
1455 1443

	
1456 1444
    /// \brief Arc map reading rule
1457 1445
    ///
1458 1446
    /// Add an arc map reading rule to the reader.
1459 1447
    template <typename Map>
1460 1448
    GraphReader& arcMap(const std::string& caption, Map& map) {
1461 1449
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1462 1450
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1463 1451
        new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1464 1452
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1465 1453
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1466 1454
        new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1467 1455
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1468 1456
      return *this;
1469 1457
    }
1470 1458

	
1471 1459
    /// \brief Arc map reading rule
1472 1460
    ///
1473 1461
    /// Add an arc map reading rule with specialized converter to the
1474 1462
    /// reader.
1475 1463
    template <typename Map, typename Converter>
1476 1464
    GraphReader& arcMap(const std::string& caption, Map& map,
1477 1465
                          const Converter& converter = Converter()) {
1478 1466
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1479 1467
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1480 1468
        new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1481 1469
        (_graph, map, converter);
1482 1470
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1483 1471
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1484 1472
        new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1485 1473
        (_graph, map, converter);
1486 1474
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1487 1475
      return *this;
1488 1476
    }
1489 1477

	
1490 1478
    /// \brief Attribute reading rule
1491 1479
    ///
1492 1480
    /// Add an attribute reading rule to the reader.
1493 1481
    template <typename Value>
1494 1482
    GraphReader& attribute(const std::string& caption, Value& value) {
1495 1483
      _reader_bits::ValueStorageBase* storage =
1496 1484
        new _reader_bits::ValueStorage<Value>(value);
1497 1485
      _attributes.insert(std::make_pair(caption, storage));
1498 1486
      return *this;
1499 1487
    }
1500 1488

	
1501 1489
    /// \brief Attribute reading rule
1502 1490
    ///
1503 1491
    /// Add an attribute reading rule with specialized converter to the
1504 1492
    /// reader.
1505 1493
    template <typename Value, typename Converter>
1506 1494
    GraphReader& attribute(const std::string& caption, Value& value,
1507 1495
                             const Converter& converter = Converter()) {
1508 1496
      _reader_bits::ValueStorageBase* storage =
1509 1497
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1510 1498
      _attributes.insert(std::make_pair(caption, storage));
1511 1499
      return *this;
1512 1500
    }
1513 1501

	
1514 1502
    /// \brief Node reading rule
1515 1503
    ///
1516 1504
    /// Add a node reading rule to reader.
1517 1505
    GraphReader& node(const std::string& caption, Node& node) {
1518 1506
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
1519 1507
      Converter converter(_node_index);
1520 1508
      _reader_bits::ValueStorageBase* storage =
1521 1509
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1522 1510
      _attributes.insert(std::make_pair(caption, storage));
1523 1511
      return *this;
1524 1512
    }
1525 1513

	
1526 1514
    /// \brief Edge reading rule
1527 1515
    ///
1528 1516
    /// Add an edge reading rule to reader.
1529 1517
    GraphReader& edge(const std::string& caption, Edge& edge) {
1530 1518
      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1531 1519
      Converter converter(_edge_index);
1532 1520
      _reader_bits::ValueStorageBase* storage =
1533 1521
        new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1534 1522
      _attributes.insert(std::make_pair(caption, storage));
1535 1523
      return *this;
1536 1524
    }
1537 1525

	
1538 1526
    /// \brief Arc reading rule
1539 1527
    ///
1540 1528
    /// Add an arc reading rule to reader.
1541 1529
    GraphReader& arc(const std::string& caption, Arc& arc) {
1542 1530
      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
1543 1531
      Converter converter(_graph, _edge_index);
1544 1532
      _reader_bits::ValueStorageBase* storage =
1545 1533
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1546 1534
      _attributes.insert(std::make_pair(caption, storage));
1547 1535
      return *this;
1548 1536
    }
1549 1537

	
1550 1538
    /// @}
1551 1539

	
1552 1540
    /// \name Select section by name
1553 1541
    /// @{
1554 1542

	
1555 1543
    /// \brief Set \c \@nodes section to be read
1556 1544
    ///
1557 1545
    /// Set \c \@nodes section to be read.
1558 1546
    GraphReader& nodes(const std::string& caption) {
1559 1547
      _nodes_caption = caption;
1560 1548
      return *this;
1561 1549
    }
1562 1550

	
1563 1551
    /// \brief Set \c \@edges section to be read
1564 1552
    ///
1565 1553
    /// Set \c \@edges section to be read.
1566 1554
    GraphReader& edges(const std::string& caption) {
1567 1555
      _edges_caption = caption;
1568 1556
      return *this;
1569 1557
    }
1570 1558

	
1571 1559
    /// \brief Set \c \@attributes section to be read
1572 1560
    ///
1573 1561
    /// Set \c \@attributes section to be read.
1574 1562
    GraphReader& attributes(const std::string& caption) {
1575 1563
      _attributes_caption = caption;
1576 1564
      return *this;
1577 1565
    }
1578 1566

	
1579 1567
    /// @}
1580 1568

	
1581 1569
    /// \name Using previously constructed node or edge set
1582 1570
    /// @{
1583 1571

	
1584 1572
    /// \brief Use previously constructed node set
1585 1573
    ///
1586 1574
    /// Use previously constructed node set, and specify the node
1587 1575
    /// label map.
1588 1576
    template <typename Map>
1589 1577
    GraphReader& useNodes(const Map& map) {
1590 1578
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1591 1579
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1592 1580
      _use_nodes = true;
1593 1581
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1594 1582
      for (NodeIt n(_graph); n != INVALID; ++n) {
1595 1583
        _node_index.insert(std::make_pair(converter(map[n]), n));
1596 1584
      }
1597 1585
      return *this;
1598 1586
    }
1599 1587

	
1600 1588
    /// \brief Use previously constructed node set
1601 1589
    ///
1602 1590
    /// Use previously constructed node set, and specify the node
1603 1591
    /// label map and a functor which converts the label map values to
1604 1592
    /// \c std::string.
1605 1593
    template <typename Map, typename Converter>
1606 1594
    GraphReader& useNodes(const Map& map,
1607 1595
                            const Converter& converter = Converter()) {
1608 1596
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1609 1597
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1610 1598
      _use_nodes = true;
1611 1599
      for (NodeIt n(_graph); n != INVALID; ++n) {
1612 1600
        _node_index.insert(std::make_pair(converter(map[n]), n));
1613 1601
      }
1614 1602
      return *this;
1615 1603
    }
1616 1604

	
1617 1605
    /// \brief Use previously constructed edge set
1618 1606
    ///
1619 1607
    /// Use previously constructed edge set, and specify the edge
1620 1608
    /// label map.
1621 1609
    template <typename Map>
1622 1610
    GraphReader& useEdges(const Map& map) {
1623 1611
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1624 1612
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1625 1613
      _use_edges = true;
1626 1614
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1627 1615
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1628 1616
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1629 1617
      }
1630 1618
      return *this;
1631 1619
    }
1632 1620

	
1633 1621
    /// \brief Use previously constructed edge set
1634 1622
    ///
1635 1623
    /// Use previously constructed edge set, and specify the edge
1636 1624
    /// label map and a functor which converts the label map values to
1637 1625
    /// \c std::string.
1638 1626
    template <typename Map, typename Converter>
1639 1627
    GraphReader& useEdges(const Map& map,
1640 1628
                            const Converter& converter = Converter()) {
1641 1629
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1642 1630
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1643 1631
      _use_edges = true;
1644 1632
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1645 1633
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1646 1634
      }
1647 1635
      return *this;
1648 1636
    }
1649 1637

	
1650 1638
    /// \brief Skip the reading of node section
1651 1639
    ///
1652 1640
    /// Omit the reading of the node section. This implies that each node
1653 1641
    /// map reading rule will be abandoned, and the nodes of the graph
1654 1642
    /// will not be constructed, which usually cause that the edge set
1655 1643
    /// could not be read due to lack of node name
1656 1644
    /// could not be read due to lack of node name resolving.
1657 1645
    /// Therefore \c skipEdges() function should also be used, or
1658 1646
    /// \c useNodes() should be used to specify the label of the nodes.
1659 1647
    GraphReader& skipNodes() {
1660 1648
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
1661 1649
      _skip_nodes = true;
1662 1650
      return *this;
1663 1651
    }
1664 1652

	
1665 1653
    /// \brief Skip the reading of edge section
1666 1654
    ///
1667 1655
    /// Omit the reading of the edge section. This implies that each edge
1668 1656
    /// map reading rule will be abandoned, and the edges of the graph
1669 1657
    /// will not be constructed.
1670 1658
    GraphReader& skipEdges() {
1671 1659
      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
1672 1660
      _skip_edges = true;
1673 1661
      return *this;
1674 1662
    }
1675 1663

	
1676 1664
    /// @}
1677 1665

	
1678 1666
  private:
1679 1667

	
1680 1668
    bool readLine() {
1681 1669
      std::string str;
1682 1670
      while(++line_num, std::getline(*_is, str)) {
1683 1671
        line.clear(); line.str(str);
1684 1672
        char c;
1685 1673
        if (line >> std::ws >> c && c != '#') {
1686 1674
          line.putback(c);
1687 1675
          return true;
1688 1676
        }
1689 1677
      }
1690 1678
      return false;
1691 1679
    }
1692 1680

	
1693 1681
    bool readSuccess() {
1694 1682
      return static_cast<bool>(*_is);
1695 1683
    }
1696 1684

	
1697 1685
    void skipSection() {
1698 1686
      char c;
1699 1687
      while (readSuccess() && line >> c && c != '@') {
1700 1688
        readLine();
1701 1689
      }
1702 1690
      line.putback(c);
1703 1691
    }
1704 1692

	
1705 1693
    void readNodes() {
1706 1694

	
1707 1695
      std::vector<int> map_index(_node_maps.size());
1708 1696
      int map_num, label_index;
1709 1697

	
1710 1698
      char c;
1711 1699
      if (!readLine() || !(line >> c) || c == '@') {
1712 1700
        if (readSuccess() && line) line.putback(c);
1713 1701
        if (!_node_maps.empty())
1714 1702
          throw FormatError("Cannot find map names");
1715 1703
        return;
1716 1704
      }
1717 1705
      line.putback(c);
1718 1706

	
1719 1707
      {
1720 1708
        std::map<std::string, int> maps;
1721 1709

	
1722 1710
        std::string map;
1723 1711
        int index = 0;
1724 1712
        while (_reader_bits::readToken(line, map)) {
1725 1713
          if (maps.find(map) != maps.end()) {
1726 1714
            std::ostringstream msg;
1727 1715
            msg << "Multiple occurence of node map: " << map;
1728 1716
            throw FormatError(msg.str());
1729 1717
          }
1730 1718
          maps.insert(std::make_pair(map, index));
1731 1719
          ++index;
1732 1720
        }
1733 1721

	
1734 1722
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1735 1723
          std::map<std::string, int>::iterator jt =
1736 1724
            maps.find(_node_maps[i].first);
1737 1725
          if (jt == maps.end()) {
1738 1726
            std::ostringstream msg;
1739 1727
            msg << "Map not found: " << _node_maps[i].first;
1740 1728
            throw FormatError(msg.str());
1741 1729
          }
1742 1730
          map_index[i] = jt->second;
1743 1731
        }
1744 1732

	
1745 1733
        {
1746 1734
          std::map<std::string, int>::iterator jt = maps.find("label");
1747 1735
          if (jt != maps.end()) {
1748 1736
            label_index = jt->second;
1749 1737
          } else {
1750 1738
            label_index = -1;
1751 1739
          }
1752 1740
        }
1753 1741
        map_num = maps.size();
1754 1742
      }
1755 1743

	
1756 1744
      while (readLine() && line >> c && c != '@') {
1757 1745
        line.putback(c);
1758 1746

	
1759 1747
        std::vector<std::string> tokens(map_num);
1760 1748
        for (int i = 0; i < map_num; ++i) {
1761 1749
          if (!_reader_bits::readToken(line, tokens[i])) {
1762 1750
            std::ostringstream msg;
1763 1751
            msg << "Column not found (" << i + 1 << ")";
1764 1752
            throw FormatError(msg.str());
1765 1753
          }
1766 1754
        }
1767 1755
        if (line >> std::ws >> c)
1768 1756
          throw FormatError("Extra character at the end of line");
1769 1757

	
1770 1758
        Node n;
1771 1759
        if (!_use_nodes) {
1772 1760
          n = _graph.addNode();
1773 1761
          if (label_index != -1)
1774 1762
            _node_index.insert(std::make_pair(tokens[label_index], n));
1775 1763
        } else {
1776 1764
          if (label_index == -1)
1777 1765
            throw FormatError("Label map not found");
1778 1766
          typename std::map<std::string, Node>::iterator it =
1779 1767
            _node_index.find(tokens[label_index]);
1780 1768
          if (it == _node_index.end()) {
1781 1769
            std::ostringstream msg;
1782 1770
            msg << "Node with label not found: " << tokens[label_index];
1783 1771
            throw FormatError(msg.str());
1784 1772
          }
1785 1773
          n = it->second;
1786 1774
        }
1787 1775

	
1788 1776
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1789 1777
          _node_maps[i].second->set(n, tokens[map_index[i]]);
1790 1778
        }
1791 1779

	
1792 1780
      }
1793 1781
      if (readSuccess()) {
1794 1782
        line.putback(c);
1795 1783
      }
1796 1784
    }
1797 1785

	
1798 1786
    void readEdges() {
1799 1787

	
1800 1788
      std::vector<int> map_index(_edge_maps.size());
1801 1789
      int map_num, label_index;
1802 1790

	
1803 1791
      char c;
1804 1792
      if (!readLine() || !(line >> c) || c == '@') {
1805 1793
        if (readSuccess() && line) line.putback(c);
1806 1794
        if (!_edge_maps.empty())
1807 1795
          throw FormatError("Cannot find map names");
1808 1796
        return;
1809 1797
      }
1810 1798
      line.putback(c);
1811 1799

	
1812 1800
      {
1813 1801
        std::map<std::string, int> maps;
1814 1802

	
1815 1803
        std::string map;
1816 1804
        int index = 0;
1817 1805
        while (_reader_bits::readToken(line, map)) {
1818 1806
          if (maps.find(map) != maps.end()) {
1819 1807
            std::ostringstream msg;
1820 1808
            msg << "Multiple occurence of edge map: " << map;
1821 1809
            throw FormatError(msg.str());
1822 1810
          }
1823 1811
          maps.insert(std::make_pair(map, index));
1824 1812
          ++index;
1825 1813
        }
1826 1814

	
1827 1815
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1828 1816
          std::map<std::string, int>::iterator jt =
1829 1817
            maps.find(_edge_maps[i].first);
1830 1818
          if (jt == maps.end()) {
1831 1819
            std::ostringstream msg;
1832 1820
            msg << "Map not found: " << _edge_maps[i].first;
1833 1821
            throw FormatError(msg.str());
1834 1822
          }
1835 1823
          map_index[i] = jt->second;
1836 1824
        }
1837 1825

	
1838 1826
        {
1839 1827
          std::map<std::string, int>::iterator jt = maps.find("label");
1840 1828
          if (jt != maps.end()) {
1841 1829
            label_index = jt->second;
1842 1830
          } else {
1843 1831
            label_index = -1;
1844 1832
          }
1845 1833
        }
1846 1834
        map_num = maps.size();
1847 1835
      }
1848 1836

	
1849 1837
      while (readLine() && line >> c && c != '@') {
1850 1838
        line.putback(c);
1851 1839

	
1852 1840
        std::string source_token;
1853 1841
        std::string target_token;
1854 1842

	
1855 1843
        if (!_reader_bits::readToken(line, source_token))
1856 1844
          throw FormatError("Node u not found");
1857 1845

	
1858 1846
        if (!_reader_bits::readToken(line, target_token))
1859 1847
          throw FormatError("Node v not found");
1860 1848

	
1861 1849
        std::vector<std::string> tokens(map_num);
1862 1850
        for (int i = 0; i < map_num; ++i) {
1863 1851
          if (!_reader_bits::readToken(line, tokens[i])) {
1864 1852
            std::ostringstream msg;
1865 1853
            msg << "Column not found (" << i + 1 << ")";
1866 1854
            throw FormatError(msg.str());
1867 1855
          }
1868 1856
        }
1869 1857
        if (line >> std::ws >> c)
1870 1858
          throw FormatError("Extra character at the end of line");
1871 1859

	
1872 1860
        Edge e;
1873 1861
        if (!_use_edges) {
1874 1862

	
1875 1863
          typename NodeIndex::iterator it;
1876 1864

	
1877 1865
          it = _node_index.find(source_token);
1878 1866
          if (it == _node_index.end()) {
1879 1867
            std::ostringstream msg;
1880 1868
            msg << "Item not found: " << source_token;
1881 1869
            throw FormatError(msg.str());
1882 1870
          }
1883 1871
          Node source = it->second;
1884 1872

	
1885 1873
          it = _node_index.find(target_token);
1886 1874
          if (it == _node_index.end()) {
1887 1875
            std::ostringstream msg;
1888 1876
            msg << "Item not found: " << target_token;
1889 1877
            throw FormatError(msg.str());
1890 1878
          }
1891 1879
          Node target = it->second;
1892 1880

	
1893 1881
          e = _graph.addEdge(source, target);
1894 1882
          if (label_index != -1)
1895 1883
            _edge_index.insert(std::make_pair(tokens[label_index], e));
1896 1884
        } else {
1897 1885
          if (label_index == -1)
1898 1886
            throw FormatError("Label map not found");
1899 1887
          typename std::map<std::string, Edge>::iterator it =
1900 1888
            _edge_index.find(tokens[label_index]);
1901 1889
          if (it == _edge_index.end()) {
1902 1890
            std::ostringstream msg;
1903 1891
            msg << "Edge with label not found: " << tokens[label_index];
1904 1892
            throw FormatError(msg.str());
1905 1893
          }
1906 1894
          e = it->second;
1907 1895
        }
1908 1896

	
1909 1897
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1910 1898
          _edge_maps[i].second->set(e, tokens[map_index[i]]);
1911 1899
        }
1912 1900

	
1913 1901
      }
1914 1902
      if (readSuccess()) {
1915 1903
        line.putback(c);
1916 1904
      }
1917 1905
    }
1918 1906

	
1919 1907
    void readAttributes() {
1920 1908

	
1921 1909
      std::set<std::string> read_attr;
1922 1910

	
1923 1911
      char c;
1924 1912
      while (readLine() && line >> c && c != '@') {
1925 1913
        line.putback(c);
1926 1914

	
1927 1915
        std::string attr, token;
1928 1916
        if (!_reader_bits::readToken(line, attr))
1929 1917
          throw FormatError("Attribute name not found");
1930 1918
        if (!_reader_bits::readToken(line, token))
1931 1919
          throw FormatError("Attribute value not found");
1932 1920
        if (line >> c)
1933 1921
          throw FormatError("Extra character at the end of line");
1934 1922

	
1935 1923
        {
1936 1924
          std::set<std::string>::iterator it = read_attr.find(attr);
1937 1925
          if (it != read_attr.end()) {
1938 1926
            std::ostringstream msg;
1939 1927
            msg << "Multiple occurence of attribute: " << attr;
1940 1928
            throw FormatError(msg.str());
1941 1929
          }
1942 1930
          read_attr.insert(attr);
1943 1931
        }
1944 1932

	
1945 1933
        {
1946 1934
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1947 1935
          while (it != _attributes.end() && it->first == attr) {
1948 1936
            it->second->set(token);
1949 1937
            ++it;
1950 1938
          }
1951 1939
        }
1952 1940

	
1953 1941
      }
1954 1942
      if (readSuccess()) {
1955 1943
        line.putback(c);
1956 1944
      }
1957 1945
      for (typename Attributes::iterator it = _attributes.begin();
1958 1946
           it != _attributes.end(); ++it) {
1959 1947
        if (read_attr.find(it->first) == read_attr.end()) {
1960 1948
          std::ostringstream msg;
1961 1949
          msg << "Attribute not found: " << it->first;
1962 1950
          throw FormatError(msg.str());
1963 1951
        }
1964 1952
      }
1965 1953
    }
1966 1954

	
1967 1955
  public:
1968 1956

	
1969 1957
    /// \name Execution of the reader
1970 1958
    /// @{
1971 1959

	
1972 1960
    /// \brief Start the batch processing
1973 1961
    ///
1974 1962
    /// This function starts the batch processing
1975 1963
    void run() {
1976 1964

	
1977 1965
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1978 1966

	
1979 1967
      bool nodes_done = _skip_nodes;
1980 1968
      bool edges_done = _skip_edges;
1981 1969
      bool attributes_done = false;
1982 1970

	
1983 1971
      line_num = 0;
1984 1972
      readLine();
1985 1973
      skipSection();
1986 1974

	
1987 1975
      while (readSuccess()) {
1988 1976
        try {
1989 1977
          char c;
1990 1978
          std::string section, caption;
1991 1979
          line >> c;
1992 1980
          _reader_bits::readToken(line, section);
1993 1981
          _reader_bits::readToken(line, caption);
1994 1982

	
1995 1983
          if (line >> c)
1996 1984
            throw FormatError("Extra character at the end of line");
1997 1985

	
1998 1986
          if (section == "nodes" && !nodes_done) {
1999 1987
            if (_nodes_caption.empty() || _nodes_caption == caption) {
2000 1988
              readNodes();
2001 1989
              nodes_done = true;
2002 1990
            }
2003 1991
          } else if ((section == "edges" || section == "arcs") &&
2004 1992
                     !edges_done) {
2005 1993
            if (_edges_caption.empty() || _edges_caption == caption) {
2006 1994
              readEdges();
2007 1995
              edges_done = true;
2008 1996
            }
2009 1997
          } else if (section == "attributes" && !attributes_done) {
2010 1998
            if (_attributes_caption.empty() || _attributes_caption == caption) {
2011 1999
              readAttributes();
2012 2000
              attributes_done = true;
2013 2001
            }
2014 2002
          } else {
2015 2003
            readLine();
2016 2004
            skipSection();
2017 2005
          }
2018 2006
        } catch (FormatError& error) {
2019 2007
          error.line(line_num);
2020 2008
          error.file(_filename);
2021 2009
          throw;
2022 2010
        }
2023 2011
      }
2024 2012

	
2025 2013
      if (!nodes_done) {
2026 2014
        throw FormatError("Section @nodes not found");
2027 2015
      }
2028 2016

	
2029 2017
      if (!edges_done) {
2030 2018
        throw FormatError("Section @edges not found");
2031 2019
      }
2032 2020

	
2033 2021
      if (!attributes_done && !_attributes.empty()) {
2034 2022
        throw FormatError("Section @attributes not found");
2035 2023
      }
2036 2024

	
2037 2025
    }
2038 2026

	
2039 2027
    /// @}
2040 2028

	
2041 2029
  };
2042 2030

	
2031
  /// \brief Return a \ref GraphReader class
2032
  ///
2033
  /// This function just returns a \ref GraphReader class.
2034
  /// \relates GraphReader
2035
  template <typename Graph>
2036
  GraphReader<Graph> graphReader(Graph& graph, std::istream& is) {
2037
    GraphReader<Graph> tmp(graph, is);
2038
    return tmp;
2039
  }
2040

	
2041
  /// \brief Return a \ref GraphReader class
2042
  ///
2043
  /// This function just returns a \ref GraphReader class.
2044
  /// \relates GraphReader
2045
  template <typename Graph>
2046
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
2047
    GraphReader<Graph> tmp(graph, fn);
2048
    return tmp;
2049
  }
2050

	
2051
  /// \brief Return a \ref GraphReader class
2052
  ///
2053
  /// This function just returns a \ref GraphReader class.
2054
  /// \relates GraphReader
2055
  template <typename Graph>
2056
  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
2057
    GraphReader<Graph> tmp(graph, fn);
2058
    return tmp;
2059
  }
2060

	
2043 2061
  class SectionReader;
2044 2062

	
2045 2063
  SectionReader sectionReader(std::istream& is);
2046 2064
  SectionReader sectionReader(const std::string& fn);
2047 2065
  SectionReader sectionReader(const char* fn);
2048 2066

	
2049 2067
  /// \ingroup lemon_io
2050 2068
  ///
2051 2069
  /// \brief Section reader class
2052 2070
  ///
2053 2071
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
2054 2072
  /// which contain any data in arbitrary format. Such sections can be
2055 2073
  /// read with this class. A reading rule can be added to the class
2056 2074
  /// with two different functions. With the \c sectionLines() function a
2057 2075
  /// functor can process the section line-by-line, while with the \c
2058 2076
  /// sectionStream() member the section can be read from an input
2059 2077
  /// stream.
2060 2078
  class SectionReader {
2061 2079
  private:
2062 2080

	
2063 2081
    std::istream* _is;
2064 2082
    bool local_is;
2065 2083
    std::string _filename;
2066 2084

	
2067 2085
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2068 2086
    Sections _sections;
2069 2087

	
2070 2088
    int line_num;
2071 2089
    std::istringstream line;
2072 2090

	
2073 2091
  public:
2074 2092

	
2075 2093
    /// \brief Constructor
2076 2094
    ///
2077 2095
    /// Construct a section reader, which reads from the given input
2078 2096
    /// stream.
2079 2097
    SectionReader(std::istream& is)
2080 2098
      : _is(&is), local_is(false) {}
2081 2099

	
2082 2100
    /// \brief Constructor
2083 2101
    ///
2084 2102
    /// Construct a section reader, which reads from the given file.
2085 2103
    SectionReader(const std::string& fn)
2086 2104
      : _is(new std::ifstream(fn.c_str())), local_is(true),
2087 2105
        _filename(fn) {
2088 2106
      if (!(*_is)) {
2089 2107
        delete _is;
2090 2108
        throw IoError("Cannot open file", fn);
2091 2109
      }
2092 2110
    }
2093 2111

	
2094 2112
    /// \brief Constructor
2095 2113
    ///
2096 2114
    /// Construct a section reader, which reads from the given file.
2097 2115
    SectionReader(const char* fn)
2098 2116
      : _is(new std::ifstream(fn)), local_is(true),
2099 2117
        _filename(fn) {
2100 2118
      if (!(*_is)) {
2101 2119
        delete _is;
2102 2120
        throw IoError("Cannot open file", fn);
2103 2121
      }
2104 2122
    }
2105 2123

	
2106 2124
    /// \brief Destructor
2107 2125
    ~SectionReader() {
2108 2126
      for (Sections::iterator it = _sections.begin();
2109 2127
           it != _sections.end(); ++it) {
2110 2128
        delete it->second;
2111 2129
      }
2112 2130

	
2113 2131
      if (local_is) {
2114 2132
        delete _is;
2115 2133
      }
2116 2134

	
2117 2135
    }
2118 2136

	
2119 2137
  private:
2120 2138

	
2121 2139
    friend SectionReader sectionReader(std::istream& is);
2122 2140
    friend SectionReader sectionReader(const std::string& fn);
2123 2141
    friend SectionReader sectionReader(const char* fn);
2124 2142

	
2125 2143
    SectionReader(SectionReader& other)
2126 2144
      : _is(other._is), local_is(other.local_is) {
2127 2145

	
2128 2146
      other._is = 0;
2129 2147
      other.local_is = false;
2130 2148

	
2131 2149
      _sections.swap(other._sections);
2132 2150
    }
2133 2151

	
2134 2152
    SectionReader& operator=(const SectionReader&);
2135 2153

	
2136 2154
  public:
2137 2155

	
2138 2156
    /// \name Section readers
2139 2157
    /// @{
2140 2158

	
2141 2159
    /// \brief Add a section processor with line oriented reading
2142 2160
    ///
2143 2161
    /// The first parameter is the type descriptor of the section, the
2144 2162
    /// second is a functor, which takes just one \c std::string
2145 2163
    /// parameter. At the reading process, each line of the section
2146 2164
    /// will be given to the functor object. However, the empty lines
2147 2165
    /// and the comment lines are filtered out, and the leading
2148 2166
    /// whitespaces are trimmed from each processed string.
2149 2167
    ///
2150 2168
    /// For example let's see a section, which contain several
2151 2169
    /// integers, which should be inserted into a vector.
2152 2170
    ///\code
2153 2171
    ///  @numbers
2154 2172
    ///  12 45 23
2155 2173
    ///  4
2156 2174
    ///  23 6
2157 2175
    ///\endcode
2158 2176
    ///
2159 2177
    /// The functor is implemented as a struct:
2160 2178
    ///\code
2161 2179
    ///  struct NumberSection {
2162 2180
    ///    std::vector<int>& _data;
2163 2181
    ///    NumberSection(std::vector<int>& data) : _data(data) {}
2164 2182
    ///    void operator()(const std::string& line) {
2165 2183
    ///      std::istringstream ls(line);
2166 2184
    ///      int value;
2167 2185
    ///      while (ls >> value) _data.push_back(value);
2168 2186
    ///    }
2169 2187
    ///  };
2170 2188
    ///
2171 2189
    ///  // ...
2172 2190
    ///
2173 2191
    ///  reader.sectionLines("numbers", NumberSection(vec));
2174 2192
    ///\endcode
2175 2193
    template <typename Functor>
2176 2194
    SectionReader& sectionLines(const std::string& type, Functor functor) {
2177 2195
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2178 2196
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2179 2197
                   "Multiple reading of section.");
2180 2198
      _sections.insert(std::make_pair(type,
2181 2199
        new _reader_bits::LineSection<Functor>(functor)));
2182 2200
      return *this;
2183 2201
    }
2184 2202

	
2185 2203

	
2186 2204
    /// \brief Add a section processor with stream oriented reading
2187 2205
    ///
2188 2206
    /// The first parameter is the type of the section, the second is
2189 2207
    /// a functor, which takes an \c std::istream& and an \c int&
2190 2208
    /// parameter, the latter regard to the line number of stream. The
2191 2209
    /// functor can read the input while the section go on, and the
2192 2210
    /// line number should be modified accordingly.
2193 2211
    template <typename Functor>
2194 2212
    SectionReader& sectionStream(const std::string& type, Functor functor) {
2195 2213
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2196 2214
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2197 2215
                   "Multiple reading of section.");
2198 2216
      _sections.insert(std::make_pair(type,
2199 2217
         new _reader_bits::StreamSection<Functor>(functor)));
2200 2218
      return *this;
2201 2219
    }
2202 2220

	
2203 2221
    /// @}
2204 2222

	
2205 2223
  private:
2206 2224

	
2207 2225
    bool readLine() {
2208 2226
      std::string str;
2209 2227
      while(++line_num, std::getline(*_is, str)) {
2210 2228
        line.clear(); line.str(str);
2211 2229
        char c;
2212 2230
        if (line >> std::ws >> c && c != '#') {
2213 2231
          line.putback(c);
2214 2232
          return true;
2215 2233
        }
2216 2234
      }
2217 2235
      return false;
2218 2236
    }
2219 2237

	
2220 2238
    bool readSuccess() {
2221 2239
      return static_cast<bool>(*_is);
2222 2240
    }
2223 2241

	
2224 2242
    void skipSection() {
2225 2243
      char c;
2226 2244
      while (readSuccess() && line >> c && c != '@') {
2227 2245
        readLine();
2228 2246
      }
2229 2247
      line.putback(c);
2230 2248
    }
2231 2249

	
2232 2250
  public:
2233 2251

	
2234 2252

	
2235 2253
    /// \name Execution of the reader
2236 2254
    /// @{
2237 2255

	
2238 2256
    /// \brief Start the batch processing
2239 2257
    ///
2240 2258
    /// This function starts the batch processing.
2241 2259
    void run() {
2242 2260

	
2243 2261
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2244 2262

	
2245 2263
      std::set<std::string> extra_sections;
2246 2264

	
2247 2265
      line_num = 0;
2248 2266
      readLine();
2249 2267
      skipSection();
2250 2268

	
2251 2269
      while (readSuccess()) {
2252 2270
        try {
2253 2271
          char c;
2254 2272
          std::string section, caption;
2255 2273
          line >> c;
2256 2274
          _reader_bits::readToken(line, section);
2257 2275
          _reader_bits::readToken(line, caption);
2258 2276

	
2259 2277
          if (line >> c)
2260 2278
            throw FormatError("Extra character at the end of line");
2261 2279

	
2262 2280
          if (extra_sections.find(section) != extra_sections.end()) {
2263 2281
            std::ostringstream msg;
2264 2282
            msg << "Multiple occurence of section: " << section;
2265 2283
            throw FormatError(msg.str());
2266 2284
          }
2267 2285
          Sections::iterator it = _sections.find(section);
2268 2286
          if (it != _sections.end()) {
2269 2287
            extra_sections.insert(section);
2270 2288
            it->second->process(*_is, line_num);
2271 2289
          }
2272 2290
          readLine();
2273 2291
          skipSection();
2274 2292
        } catch (FormatError& error) {
2275 2293
          error.line(line_num);
2276 2294
          error.file(_filename);
2277 2295
          throw;
2278 2296
        }
2279 2297
      }
2280 2298
      for (Sections::iterator it = _sections.begin();
2281 2299
           it != _sections.end(); ++it) {
2282 2300
        if (extra_sections.find(it->first) == extra_sections.end()) {
2283 2301
          std::ostringstream os;
2284 2302
          os << "Cannot find section: " << it->first;
2285 2303
          throw FormatError(os.str());
2286 2304
        }
2287 2305
      }
2288 2306
    }
2289 2307

	
2290 2308
    /// @}
2291 2309

	
2292 2310
  };
2293 2311

	
2294 2312
  /// \brief Return a \ref SectionReader class
2295 2313
  ///
2296 2314
  /// This function just returns a \ref SectionReader class.
2297 2315
  /// \relates SectionReader
2298 2316
  inline SectionReader sectionReader(std::istream& is) {
2299 2317
    SectionReader tmp(is);
2300 2318
    return tmp;
2301 2319
  }
2302 2320

	
2303 2321
  /// \brief Return a \ref SectionReader class
2304 2322
  ///
2305 2323
  /// This function just returns a \ref SectionReader class.
2306 2324
  /// \relates SectionReader
2307 2325
  inline SectionReader sectionReader(const std::string& fn) {
2308 2326
    SectionReader tmp(fn);
2309 2327
    return tmp;
2310 2328
  }
2311 2329

	
2312 2330
  /// \brief Return a \ref SectionReader class
2313 2331
  ///
2314 2332
  /// This function just returns a \ref SectionReader class.
2315 2333
  /// \relates SectionReader
2316 2334
  inline SectionReader sectionReader(const char* fn) {
2317 2335
    SectionReader tmp(fn);
2318 2336
    return tmp;
2319 2337
  }
2320 2338

	
2321 2339
  /// \ingroup lemon_io
2322 2340
  ///
2323 2341
  /// \brief Reader for the contents of the \ref lgf-format "LGF" file
2324 2342
  ///
2325 2343
  /// This class can be used to read the sections, the map names and
2326 2344
  /// the attributes from a file. Usually, the LEMON programs know
2327 2345
  /// that, which type of graph, which maps and which attributes
2328 2346
  /// should be read from a file, but in general tools (like glemon)
2329 2347
  /// the contents of an LGF file should be guessed somehow. This class
2330 2348
  /// reads the graph and stores the appropriate information for
2331 2349
  /// reading the graph.
2332 2350
  ///
2333 2351
  ///\code
2334 2352
  /// LgfContents contents("graph.lgf");
2335 2353
  /// contents.run();
2336 2354
  ///
2337 2355
  /// // Does it contain any node section and arc section?
2338 2356
  /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
2339 2357
  ///   std::cerr << "Failure, cannot find graph." << std::endl;
2340 2358
  ///   return -1;
2341 2359
  /// }
2342 2360
  /// std::cout << "The name of the default node section: "
2343 2361
  ///           << contents.nodeSection(0) << std::endl;
2344 2362
  /// std::cout << "The number of the arc maps: "
2345 2363
  ///           << contents.arcMaps(0).size() << std::endl;
2346 2364
  /// std::cout << "The name of second arc map: "
2347 2365
  ///           << contents.arcMaps(0)[1] << std::endl;
2348 2366
  ///\endcode
2349 2367
  class LgfContents {
2350 2368
  private:
2351 2369

	
2352 2370
    std::istream* _is;
2353 2371
    bool local_is;
2354 2372

	
2355 2373
    std::vector<std::string> _node_sections;
2356 2374
    std::vector<std::string> _edge_sections;
2357 2375
    std::vector<std::string> _attribute_sections;
2358 2376
    std::vector<std::string> _extra_sections;
2359 2377

	
2360 2378
    std::vector<bool> _arc_sections;
2361 2379

	
2362 2380
    std::vector<std::vector<std::string> > _node_maps;
2363 2381
    std::vector<std::vector<std::string> > _edge_maps;
2364 2382

	
2365 2383
    std::vector<std::vector<std::string> > _attributes;
2366 2384

	
2367 2385

	
2368 2386
    int line_num;
2369 2387
    std::istringstream line;
2370 2388

	
2371 2389
  public:
2372 2390

	
2373 2391
    /// \brief Constructor
2374 2392
    ///
2375 2393
    /// Construct an \e LGF contents reader, which reads from the given
2376 2394
    /// input stream.
2377 2395
    LgfContents(std::istream& is)
2378 2396
      : _is(&is), local_is(false) {}
2379 2397

	
2380 2398
    /// \brief Constructor
2381 2399
    ///
2382 2400
    /// Construct an \e LGF contents reader, which reads from the given
2383 2401
    /// file.
2384 2402
    LgfContents(const std::string& fn)
2385 2403
      : _is(new std::ifstream(fn.c_str())), local_is(true) {
2386 2404
      if (!(*_is)) {
2387 2405
        delete _is;
2388 2406
        throw IoError("Cannot open file", fn);
2389 2407
      }
2390 2408
    }
2391 2409

	
2392 2410
    /// \brief Constructor
2393 2411
    ///
2394 2412
    /// Construct an \e LGF contents reader, which reads from the given
2395 2413
    /// file.
2396 2414
    LgfContents(const char* fn)
2397 2415
      : _is(new std::ifstream(fn)), local_is(true) {
2398 2416
      if (!(*_is)) {
2399 2417
        delete _is;
2400 2418
        throw IoError("Cannot open file", fn);
2401 2419
      }
2402 2420
    }
2403 2421

	
2404 2422
    /// \brief Destructor
2405 2423
    ~LgfContents() {
2406 2424
      if (local_is) delete _is;
2407 2425
    }
2408 2426

	
2409 2427
  private:
2410 2428

	
2411 2429
    LgfContents(const LgfContents&);
2412 2430
    LgfContents& operator=(const LgfContents&);
2413 2431

	
2414 2432
  public:
2415 2433

	
2416 2434

	
2417 2435
    /// \name Node sections
2418 2436
    /// @{
2419 2437

	
2420 2438
    /// \brief Gives back the number of node sections in the file.
2421 2439
    ///
2422 2440
    /// Gives back the number of node sections in the file.
2423 2441
    int nodeSectionNum() const {
2424 2442
      return _node_sections.size();
2425 2443
    }
2426 2444

	
2427 2445
    /// \brief Returns the node section name at the given position.
2428 2446
    ///
2429 2447
    /// Returns the node section name at the given position.
2430 2448
    const std::string& nodeSection(int i) const {
2431 2449
      return _node_sections[i];
2432 2450
    }
2433 2451

	
2434 2452
    /// \brief Gives back the node maps for the given section.
2435 2453
    ///
2436 2454
    /// Gives back the node maps for the given section.
2437 2455
    const std::vector<std::string>& nodeMapNames(int i) const {
2438 2456
      return _node_maps[i];
2439 2457
    }
2440 2458

	
2441 2459
    /// @}
2442 2460

	
2443 2461
    /// \name Arc/Edge sections
2444 2462
    /// @{
2445 2463

	
2446 2464
    /// \brief Gives back the number of arc/edge sections in the file.
2447 2465
    ///
2448 2466
    /// Gives back the number of arc/edge sections in the file.
2449 2467
    /// \note It is synonym of \c edgeSectionNum().
2450 2468
    int arcSectionNum() const {
2451 2469
      return _edge_sections.size();
2452 2470
    }
2453 2471

	
2454 2472
    /// \brief Returns the arc/edge section name at the given position.
2455 2473
    ///
2456 2474
    /// Returns the arc/edge section name at the given position.
2457 2475
    /// \note It is synonym of \c edgeSection().
2458 2476
    const std::string& arcSection(int i) const {
2459 2477
      return _edge_sections[i];
2460 2478
    }
2461 2479

	
2462 2480
    /// \brief Gives back the arc/edge maps for the given section.
2463 2481
    ///
2464 2482
    /// Gives back the arc/edge maps for the given section.
2465 2483
    /// \note It is synonym of \c edgeMapNames().
2466 2484
    const std::vector<std::string>& arcMapNames(int i) const {
2467 2485
      return _edge_maps[i];
2468 2486
    }
2469 2487

	
2470 2488
    /// @}
2471 2489

	
2472 2490
    /// \name Synonyms
2473 2491
    /// @{
2474 2492

	
2475 2493
    /// \brief Gives back the number of arc/edge sections in the file.
2476 2494
    ///
2477 2495
    /// Gives back the number of arc/edge sections in the file.
2478 2496
    /// \note It is synonym of \c arcSectionNum().
2479 2497
    int edgeSectionNum() const {
2480 2498
      return _edge_sections.size();
2481 2499
    }
2482 2500

	
2483 2501
    /// \brief Returns the section name at the given position.
2484 2502
    ///
2485 2503
    /// Returns the section name at the given position.
2486 2504
    /// \note It is synonym of \c arcSection().
2487 2505
    const std::string& edgeSection(int i) const {
2488 2506
      return _edge_sections[i];
2489 2507
    }
2490 2508

	
2491 2509
    /// \brief Gives back the edge maps for the given section.
2492 2510
    ///
2493 2511
    /// Gives back the edge maps for the given section.
2494 2512
    /// \note It is synonym of \c arcMapNames().
2495 2513
    const std::vector<std::string>& edgeMapNames(int i) const {
2496 2514
      return _edge_maps[i];
2497 2515
    }
2498 2516

	
2499 2517
    /// @}
2500 2518

	
2501 2519
    /// \name Attribute sections
2502 2520
    /// @{
2503 2521

	
2504 2522
    /// \brief Gives back the number of attribute sections in the file.
2505 2523
    ///
2506 2524
    /// Gives back the number of attribute sections in the file.
2507 2525
    int attributeSectionNum() const {
2508 2526
      return _attribute_sections.size();
2509 2527
    }
2510 2528

	
2511 2529
    /// \brief Returns the attribute section name at the given position.
2512 2530
    ///
2513 2531
    /// Returns the attribute section name at the given position.
2514 2532
    const std::string& attributeSectionNames(int i) const {
2515 2533
      return _attribute_sections[i];
2516 2534
    }
2517 2535

	
2518 2536
    /// \brief Gives back the attributes for the given section.
2519 2537
    ///
2520 2538
    /// Gives back the attributes for the given section.
2521 2539
    const std::vector<std::string>& attributes(int i) const {
2522 2540
      return _attributes[i];
2523 2541
    }
2524 2542

	
2525 2543
    /// @}
2526 2544

	
2527 2545
    /// \name Extra sections
2528 2546
    /// @{
2529 2547

	
2530 2548
    /// \brief Gives back the number of extra sections in the file.
2531 2549
    ///
2532 2550
    /// Gives back the number of extra sections in the file.
2533 2551
    int extraSectionNum() const {
2534 2552
      return _extra_sections.size();
2535 2553
    }
2536 2554

	
2537 2555
    /// \brief Returns the extra section type at the given position.
2538 2556
    ///
2539 2557
    /// Returns the section type at the given position.
2540 2558
    const std::string& extraSection(int i) const {
2541 2559
      return _extra_sections[i];
2542 2560
    }
2543 2561

	
2544 2562
    /// @}
2545 2563

	
2546 2564
  private:
2547 2565

	
2548 2566
    bool readLine() {
2549 2567
      std::string str;
2550 2568
      while(++line_num, std::getline(*_is, str)) {
2551 2569
        line.clear(); line.str(str);
2552 2570
        char c;
2553 2571
        if (line >> std::ws >> c && c != '#') {
2554 2572
          line.putback(c);
2555 2573
          return true;
2556 2574
        }
2557 2575
      }
2558 2576
      return false;
2559 2577
    }
2560 2578

	
2561 2579
    bool readSuccess() {
2562 2580
      return static_cast<bool>(*_is);
2563 2581
    }
2564 2582

	
2565 2583
    void skipSection() {
2566 2584
      char c;
2567 2585
      while (readSuccess() && line >> c && c != '@') {
2568 2586
        readLine();
2569 2587
      }
2570 2588
      line.putback(c);
2571 2589
    }
2572 2590

	
2573 2591
    void readMaps(std::vector<std::string>& maps) {
2574 2592
      char c;
2575 2593
      if (!readLine() || !(line >> c) || c == '@') {
2576 2594
        if (readSuccess() && line) line.putback(c);
2577 2595
        return;
2578 2596
      }
2579 2597
      line.putback(c);
2580 2598
      std::string map;
2581 2599
      while (_reader_bits::readToken(line, map)) {
2582 2600
        maps.push_back(map);
2583 2601
      }
2584 2602
    }
2585 2603

	
2586 2604
    void readAttributes(std::vector<std::string>& attrs) {
2587 2605
      readLine();
2588 2606
      char c;
2589 2607
      while (readSuccess() && line >> c && c != '@') {
2590 2608
        line.putback(c);
2591 2609
        std::string attr;
2592 2610
        _reader_bits::readToken(line, attr);
2593 2611
        attrs.push_back(attr);
2594 2612
        readLine();
2595 2613
      }
2596 2614
      line.putback(c);
2597 2615
    }
2598 2616

	
2599 2617
  public:
2600 2618

	
2601 2619
    /// \name Execution of the contents reader
2602 2620
    /// @{
2603 2621

	
2604 2622
    /// \brief Starts the reading
2605 2623
    ///
2606 2624
    /// This function starts the reading.
2607 2625
    void run() {
2608 2626

	
2609 2627
      readLine();
2610 2628
      skipSection();
2611 2629

	
2612 2630
      while (readSuccess()) {
2613 2631

	
2614 2632
        char c;
2615 2633
        line >> c;
2616 2634

	
2617 2635
        std::string section, caption;
2618 2636
        _reader_bits::readToken(line, section);
2619 2637
        _reader_bits::readToken(line, caption);
2620 2638

	
2621 2639
        if (section == "nodes") {
2622 2640
          _node_sections.push_back(caption);
2623 2641
          _node_maps.push_back(std::vector<std::string>());
2624 2642
          readMaps(_node_maps.back());
2625 2643
          readLine(); skipSection();
2626 2644
        } else if (section == "arcs" || section == "edges") {
2627 2645
          _edge_sections.push_back(caption);
2628 2646
          _arc_sections.push_back(section == "arcs");
2629 2647
          _edge_maps.push_back(std::vector<std::string>());
2630 2648
          readMaps(_edge_maps.back());
2631 2649
          readLine(); skipSection();
2632 2650
        } else if (section == "attributes") {
2633 2651
          _attribute_sections.push_back(caption);
2634 2652
          _attributes.push_back(std::vector<std::string>());
2635 2653
          readAttributes(_attributes.back());
2636 2654
        } else {
2637 2655
          _extra_sections.push_back(section);
2638 2656
          readLine(); skipSection();
2639 2657
        }
2640 2658
      }
2641 2659
    }
2642 2660

	
2643 2661
    /// @}
2644 2662

	
2645 2663
  };
2646 2664
}
2647 2665

	
2648 2666
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\ingroup lemon_io
20 20
///\file
21 21
///\brief \ref lgf-format "LEMON Graph Format" writer.
22 22

	
23 23

	
24 24
#ifndef LEMON_LGF_WRITER_H
25 25
#define LEMON_LGF_WRITER_H
26 26

	
27 27
#include <iostream>
28 28
#include <fstream>
29 29
#include <sstream>
30 30

	
31 31
#include <algorithm>
32 32

	
33 33
#include <vector>
34 34
#include <functional>
35 35

	
36 36
#include <lemon/core.h>
37 37
#include <lemon/maps.h>
38 38

	
39 39
#include <lemon/concept_check.h>
40 40
#include <lemon/concepts/maps.h>
41 41

	
42 42
namespace lemon {
43 43

	
44 44
  namespace _writer_bits {
45 45

	
46 46
    template <typename Value>
47 47
    struct DefaultConverter {
48 48
      std::string operator()(const Value& value) {
49 49
        std::ostringstream os;
50 50
        os << value;
51 51
        return os.str();
52 52
      }
53 53
    };
54 54

	
55 55
    template <typename T>
56 56
    bool operator<(const T&, const T&) {
57 57
      throw FormatError("Label map is not comparable");
58 58
    }
59 59

	
60 60
    template <typename _Map>
61 61
    class MapLess {
62 62
    public:
63 63
      typedef _Map Map;
64 64
      typedef typename Map::Key Item;
65 65

	
66 66
    private:
67 67
      const Map& _map;
68 68

	
69 69
    public:
70 70
      MapLess(const Map& map) : _map(map) {}
71 71

	
72 72
      bool operator()(const Item& left, const Item& right) {
73 73
        return _map[left] < _map[right];
74 74
      }
75 75
    };
76 76

	
77 77
    template <typename _Graph, bool _dir, typename _Map>
78 78
    class GraphArcMapLess {
79 79
    public:
80 80
      typedef _Map Map;
81 81
      typedef _Graph Graph;
82 82
      typedef typename Graph::Edge Item;
83 83

	
84 84
    private:
85 85
      const Graph& _graph;
86 86
      const Map& _map;
87 87

	
88 88
    public:
89 89
      GraphArcMapLess(const Graph& graph, const Map& map)
90 90
        : _graph(graph), _map(map) {}
91 91

	
92 92
      bool operator()(const Item& left, const Item& right) {
93 93
        return _map[_graph.direct(left, _dir)] <
94 94
          _map[_graph.direct(right, _dir)];
95 95
      }
96 96
    };
97 97

	
98 98
    template <typename _Item>
99 99
    class MapStorageBase {
100 100
    public:
101 101
      typedef _Item Item;
102 102

	
103 103
    public:
104 104
      MapStorageBase() {}
105 105
      virtual ~MapStorageBase() {}
106 106

	
107 107
      virtual std::string get(const Item& item) = 0;
108 108
      virtual void sort(std::vector<Item>&) = 0;
109 109
    };
110 110

	
111 111
    template <typename _Item, typename _Map,
112 112
              typename _Converter = DefaultConverter<typename _Map::Value> >
113 113
    class MapStorage : public MapStorageBase<_Item> {
114 114
    public:
115 115
      typedef _Map Map;
116 116
      typedef _Converter Converter;
117 117
      typedef _Item Item;
118 118

	
119 119
    private:
120 120
      const Map& _map;
121 121
      Converter _converter;
122 122

	
123 123
    public:
124 124
      MapStorage(const Map& map, const Converter& converter = Converter())
125 125
        : _map(map), _converter(converter) {}
126 126
      virtual ~MapStorage() {}
127 127

	
128 128
      virtual std::string get(const Item& item) {
129 129
        return _converter(_map[item]);
130 130
      }
131 131
      virtual void sort(std::vector<Item>& items) {
132 132
        MapLess<Map> less(_map);
133 133
        std::sort(items.begin(), items.end(), less);
134 134
      }
135 135
    };
136 136

	
137 137
    template <typename _Graph, bool _dir, typename _Map,
138 138
              typename _Converter = DefaultConverter<typename _Map::Value> >
139 139
    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
140 140
    public:
141 141
      typedef _Map Map;
142 142
      typedef _Converter Converter;
143 143
      typedef _Graph Graph;
144 144
      typedef typename Graph::Edge Item;
145 145
      static const bool dir = _dir;
146 146

	
147 147
    private:
148 148
      const Graph& _graph;
149 149
      const Map& _map;
150 150
      Converter _converter;
151 151

	
152 152
    public:
153 153
      GraphArcMapStorage(const Graph& graph, const Map& map,
154 154
                         const Converter& converter = Converter())
155 155
        : _graph(graph), _map(map), _converter(converter) {}
156 156
      virtual ~GraphArcMapStorage() {}
157 157

	
158 158
      virtual std::string get(const Item& item) {
159 159
        return _converter(_map[_graph.direct(item, dir)]);
160 160
      }
161 161
      virtual void sort(std::vector<Item>& items) {
162 162
        GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
163 163
        std::sort(items.begin(), items.end(), less);
164 164
      }
165 165
    };
166 166

	
167 167
    class ValueStorageBase {
168 168
    public:
169 169
      ValueStorageBase() {}
170 170
      virtual ~ValueStorageBase() {}
171 171

	
172 172
      virtual std::string get() = 0;
173 173
    };
174 174

	
175 175
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
176 176
    class ValueStorage : public ValueStorageBase {
177 177
    public:
178 178
      typedef _Value Value;
179 179
      typedef _Converter Converter;
180 180

	
181 181
    private:
182 182
      const Value& _value;
183 183
      Converter _converter;
184 184

	
185 185
    public:
186 186
      ValueStorage(const Value& value, const Converter& converter = Converter())
187 187
        : _value(value), _converter(converter) {}
188 188

	
189 189
      virtual std::string get() {
190 190
        return _converter(_value);
191 191
      }
192 192
    };
193 193

	
194 194
    template <typename Value>
195 195
    struct MapLookUpConverter {
196 196
      const std::map<Value, std::string>& _map;
197 197

	
198 198
      MapLookUpConverter(const std::map<Value, std::string>& map)
199 199
        : _map(map) {}
200 200

	
201 201
      std::string operator()(const Value& str) {
202 202
        typename std::map<Value, std::string>::const_iterator it =
203 203
          _map.find(str);
204 204
        if (it == _map.end()) {
205 205
          throw FormatError("Item not found");
206 206
        }
207 207
        return it->second;
208 208
      }
209 209
    };
210 210

	
211 211
    template <typename Graph>
212 212
    struct GraphArcLookUpConverter {
213 213
      const Graph& _graph;
214 214
      const std::map<typename Graph::Edge, std::string>& _map;
215 215

	
216 216
      GraphArcLookUpConverter(const Graph& graph,
217 217
                              const std::map<typename Graph::Edge,
218 218
                                             std::string>& map)
219 219
        : _graph(graph), _map(map) {}
220 220

	
221 221
      std::string operator()(const typename Graph::Arc& val) {
222 222
        typename std::map<typename Graph::Edge, std::string>
223 223
          ::const_iterator it = _map.find(val);
224 224
        if (it == _map.end()) {
225 225
          throw FormatError("Item not found");
226 226
        }
227 227
        return (_graph.direction(val) ? '+' : '-') + it->second;
228 228
      }
229 229
    };
230 230

	
231 231
    inline bool isWhiteSpace(char c) {
232 232
      return c == ' ' || c == '\t' || c == '\v' ||
233 233
        c == '\n' || c == '\r' || c == '\f';
234 234
    }
235 235

	
236 236
    inline bool isEscaped(char c) {
237 237
      return c == '\\' || c == '\"' || c == '\'' ||
238 238
        c == '\a' || c == '\b';
239 239
    }
240 240

	
241 241
    inline static void writeEscape(std::ostream& os, char c) {
242 242
      switch (c) {
243 243
      case '\\':
244 244
        os << "\\\\";
245 245
        return;
246 246
      case '\"':
247 247
        os << "\\\"";
248 248
        return;
249 249
      case '\a':
250 250
        os << "\\a";
251 251
        return;
252 252
      case '\b':
253 253
        os << "\\b";
254 254
        return;
255 255
      case '\f':
256 256
        os << "\\f";
257 257
        return;
258 258
      case '\r':
259 259
        os << "\\r";
260 260
        return;
261 261
      case '\n':
262 262
        os << "\\n";
263 263
        return;
264 264
      case '\t':
265 265
        os << "\\t";
266 266
        return;
267 267
      case '\v':
268 268
        os << "\\v";
269 269
        return;
270 270
      default:
271 271
        if (c < 0x20) {
272 272
          std::ios::fmtflags flags = os.flags();
273 273
          os << '\\' << std::oct << static_cast<int>(c);
274 274
          os.flags(flags);
275 275
        } else {
276 276
          os << c;
277 277
        }
278 278
        return;
279 279
      }
280 280
    }
281 281

	
282 282
    inline bool requireEscape(const std::string& str) {
283 283
      if (str.empty() || str[0] == '@') return true;
284 284
      std::istringstream is(str);
285 285
      char c;
286 286
      while (is.get(c)) {
287 287
        if (isWhiteSpace(c) || isEscaped(c)) {
288 288
          return true;
289 289
        }
290 290
      }
291 291
      return false;
292 292
    }
293 293

	
294 294
    inline std::ostream& writeToken(std::ostream& os, const std::string& str) {
295 295

	
296 296
      if (requireEscape(str)) {
297 297
        os << '\"';
298 298
        for (std::string::const_iterator it = str.begin();
299 299
             it != str.end(); ++it) {
300 300
          writeEscape(os, *it);
301 301
        }
302 302
        os << '\"';
303 303
      } else {
304 304
        os << str;
305 305
      }
306 306
      return os;
307 307
    }
308 308

	
309 309
    class Section {
310 310
    public:
311 311
      virtual ~Section() {}
312 312
      virtual void process(std::ostream& os) = 0;
313 313
    };
314 314

	
315 315
    template <typename Functor>
316 316
    class LineSection : public Section {
317 317
    private:
318 318

	
319 319
      Functor _functor;
320 320

	
321 321
    public:
322 322

	
323 323
      LineSection(const Functor& functor) : _functor(functor) {}
324 324
      virtual ~LineSection() {}
325 325

	
326 326
      virtual void process(std::ostream& os) {
327 327
        std::string line;
328 328
        while (!(line = _functor()).empty()) os << line << std::endl;
329 329
      }
330 330
    };
331 331

	
332 332
    template <typename Functor>
333 333
    class StreamSection : public Section {
334 334
    private:
335 335

	
336 336
      Functor _functor;
337 337

	
338 338
    public:
339 339

	
340 340
      StreamSection(const Functor& functor) : _functor(functor) {}
341 341
      virtual ~StreamSection() {}
342 342

	
343 343
      virtual void process(std::ostream& os) {
344 344
        _functor(os);
345 345
      }
346 346
    };
347 347

	
348 348
  }
349 349

	
350 350
  template <typename Digraph>
351 351
  class DigraphWriter;
352 352

	
353
  /// \brief Return a \ref DigraphWriter class
354
  ///
355
  /// This function just returns a \ref DigraphWriter class.
356
  /// \relates DigraphWriter
357 353
  template <typename Digraph>
358 354
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
359
                                       std::ostream& os = std::cout) {
360
    DigraphWriter<Digraph> tmp(digraph, os);
361
    return tmp;
362
  }
363

	
364
  /// \brief Return a \ref DigraphWriter class
365
  ///
366
  /// This function just returns a \ref DigraphWriter class.
367
  /// \relates DigraphWriter
355
                                       std::ostream& os = std::cout);
368 356
  template <typename Digraph>
369 357
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
370
                                       const std::string& fn) {
371
    DigraphWriter<Digraph> tmp(digraph, fn);
372
    return tmp;
373
  }
358
                                       const std::string& fn);
374 359

	
375
  /// \brief Return a \ref DigraphWriter class
376
  ///
377
  /// This function just returns a \ref DigraphWriter class.
378
  /// \relates DigraphWriter
379 360
  template <typename Digraph>
380 361
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
381
                                       const char* fn) {
382
    DigraphWriter<Digraph> tmp(digraph, fn);
383
    return tmp;
384
  }
362
                                       const char* fn);
363

	
385 364

	
386 365
  /// \ingroup lemon_io
387 366
  ///
388 367
  /// \brief \ref lgf-format "LGF" writer for directed graphs
389 368
  ///
390 369
  /// This utility writes an \ref lgf-format "LGF" file.
391 370
  ///
392 371
  /// The writing method does a batch processing. The user creates a
393 372
  /// writer object, then various writing rules can be added to the
394 373
  /// writer, and eventually the writing is executed with the \c run()
395 374
  /// member function. A map writing rule can be added to the writer
396 375
  /// with the \c nodeMap() or \c arcMap() members. An optional
397 376
  /// converter parameter can also be added as a standard functor
398 377
  /// converting from the value type of the map to \c std::string. If it
399 378
  /// is set, it will determine how the value type of the map is written to
400 379
  /// the output stream. If the functor is not set, then a default
401 380
  /// conversion will be used. The \c attribute(), \c node() and \c
402 381
  /// arc() functions are used to add attribute writing rules.
403 382
  ///
404 383
  ///\code
405 384
  /// DigraphWriter<Digraph>(digraph, std::cout).
406 385
  ///   nodeMap("coordinates", coord_map).
407 386
  ///   nodeMap("size", size).
408 387
  ///   nodeMap("title", title).
409 388
  ///   arcMap("capacity", cap_map).
410 389
  ///   node("source", src).
411 390
  ///   node("target", trg).
412 391
  ///   attribute("caption", caption).
413 392
  ///   run();
414 393
  ///\endcode
415 394
  ///
416 395
  ///
417 396
  /// By default, the writer does not write additional captions to the
418 397
  /// sections, but they can be give as an optional parameter of
419 398
  /// the \c nodes(), \c arcs() or \c
420 399
  /// attributes() functions.
421 400
  ///
422 401
  /// The \c skipNodes() and \c skipArcs() functions forbid the
423 402
  /// writing of the sections. If two arc sections should be written
424 403
  /// to the output, it can be done in two passes, the first pass
425 404
  /// writes the node section and the first arc section, then the
426 405
  /// second pass skips the node section and writes just the arc
427 406
  /// section to the stream. The output stream can be retrieved with
428 407
  /// the \c ostream() function, hence the second pass can append its
429 408
  /// output to the output of the first pass.
430 409
  template <typename _Digraph>
431 410
  class DigraphWriter {
432 411
  public:
433 412

	
434 413
    typedef _Digraph Digraph;
435 414
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
436 415

	
437 416
  private:
438 417

	
439 418

	
440 419
    std::ostream* _os;
441 420
    bool local_os;
442 421

	
443 422
    const Digraph& _digraph;
444 423

	
445 424
    std::string _nodes_caption;
446 425
    std::string _arcs_caption;
447 426
    std::string _attributes_caption;
448 427

	
449 428
    typedef std::map<Node, std::string> NodeIndex;
450 429
    NodeIndex _node_index;
451 430
    typedef std::map<Arc, std::string> ArcIndex;
452 431
    ArcIndex _arc_index;
453 432

	
454 433
    typedef std::vector<std::pair<std::string,
455 434
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
456 435
    NodeMaps _node_maps;
457 436

	
458 437
    typedef std::vector<std::pair<std::string,
459 438
      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
460 439
    ArcMaps _arc_maps;
461 440

	
462 441
    typedef std::vector<std::pair<std::string,
463 442
      _writer_bits::ValueStorageBase*> > Attributes;
464 443
    Attributes _attributes;
465 444

	
466 445
    bool _skip_nodes;
467 446
    bool _skip_arcs;
468 447

	
469 448
  public:
470 449

	
471 450
    /// \brief Constructor
472 451
    ///
473 452
    /// Construct a directed graph writer, which writes to the given
474 453
    /// output stream.
475 454
    DigraphWriter(const Digraph& digraph, std::ostream& os = std::cout)
476 455
      : _os(&os), local_os(false), _digraph(digraph),
477 456
        _skip_nodes(false), _skip_arcs(false) {}
478 457

	
479 458
    /// \brief Constructor
480 459
    ///
481 460
    /// Construct a directed graph writer, which writes to the given
482 461
    /// output file.
483 462
    DigraphWriter(const Digraph& digraph, const std::string& fn)
484 463
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
485 464
        _skip_nodes(false), _skip_arcs(false) {
486 465
      if (!(*_os)) {
487 466
        delete _os;
488 467
        throw IoError("Cannot write file", fn);
489 468
      }
490 469
    }
491 470

	
492 471
    /// \brief Constructor
493 472
    ///
494 473
    /// Construct a directed graph writer, which writes to the given
495 474
    /// output file.
496 475
    DigraphWriter(const Digraph& digraph, const char* fn)
497 476
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
498 477
        _skip_nodes(false), _skip_arcs(false) {
499 478
      if (!(*_os)) {
500 479
        delete _os;
501 480
        throw IoError("Cannot write file", fn);
502 481
      }
503 482
    }
504 483

	
505 484
    /// \brief Destructor
506 485
    ~DigraphWriter() {
507 486
      for (typename NodeMaps::iterator it = _node_maps.begin();
508 487
           it != _node_maps.end(); ++it) {
509 488
        delete it->second;
510 489
      }
511 490

	
512 491
      for (typename ArcMaps::iterator it = _arc_maps.begin();
513 492
           it != _arc_maps.end(); ++it) {
514 493
        delete it->second;
515 494
      }
516 495

	
517 496
      for (typename Attributes::iterator it = _attributes.begin();
518 497
           it != _attributes.end(); ++it) {
519 498
        delete it->second;
520 499
      }
521 500

	
522 501
      if (local_os) {
523 502
        delete _os;
524 503
      }
525 504
    }
526 505

	
527 506
  private:
528 507

	
529
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
530
                                                  std::ostream& os);
531
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
532
                                                  const std::string& fn);
533
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
534
                                                  const char *fn);
508
    template <typename DGR>
509
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph, 
510
                                            std::ostream& os);
511
    template <typename DGR>
512
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
513
                                            const std::string& fn);
514
    template <typename DGR>
515
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
516
                                            const char *fn);
535 517

	
536 518
    DigraphWriter(DigraphWriter& other)
537 519
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
538 520
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
539 521

	
540 522
      other._os = 0;
541 523
      other.local_os = false;
542 524

	
543 525
      _node_index.swap(other._node_index);
544 526
      _arc_index.swap(other._arc_index);
545 527

	
546 528
      _node_maps.swap(other._node_maps);
547 529
      _arc_maps.swap(other._arc_maps);
548 530
      _attributes.swap(other._attributes);
549 531

	
550 532
      _nodes_caption = other._nodes_caption;
551 533
      _arcs_caption = other._arcs_caption;
552 534
      _attributes_caption = other._attributes_caption;
553 535
    }
554 536

	
555 537
    DigraphWriter& operator=(const DigraphWriter&);
556 538

	
557 539
  public:
558 540

	
559 541
    /// \name Writing rules
560 542
    /// @{
561 543

	
562 544
    /// \brief Node map writing rule
563 545
    ///
564 546
    /// Add a node map writing rule to the writer.
565 547
    template <typename Map>
566 548
    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
567 549
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
568 550
      _writer_bits::MapStorageBase<Node>* storage =
569 551
        new _writer_bits::MapStorage<Node, Map>(map);
570 552
      _node_maps.push_back(std::make_pair(caption, storage));
571 553
      return *this;
572 554
    }
573 555

	
574 556
    /// \brief Node map writing rule
575 557
    ///
576 558
    /// Add a node map writing rule with specialized converter to the
577 559
    /// writer.
578 560
    template <typename Map, typename Converter>
579 561
    DigraphWriter& nodeMap(const std::string& caption, const Map& map,
580 562
                           const Converter& converter = Converter()) {
581 563
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
582 564
      _writer_bits::MapStorageBase<Node>* storage =
583 565
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
584 566
      _node_maps.push_back(std::make_pair(caption, storage));
585 567
      return *this;
586 568
    }
587 569

	
588 570
    /// \brief Arc map writing rule
589 571
    ///
590 572
    /// Add an arc map writing rule to the writer.
591 573
    template <typename Map>
592 574
    DigraphWriter& arcMap(const std::string& caption, const Map& map) {
593 575
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
594 576
      _writer_bits::MapStorageBase<Arc>* storage =
595 577
        new _writer_bits::MapStorage<Arc, Map>(map);
596 578
      _arc_maps.push_back(std::make_pair(caption, storage));
597 579
      return *this;
598 580
    }
599 581

	
600 582
    /// \brief Arc map writing rule
601 583
    ///
602 584
    /// Add an arc map writing rule with specialized converter to the
603 585
    /// writer.
604 586
    template <typename Map, typename Converter>
605 587
    DigraphWriter& arcMap(const std::string& caption, const Map& map,
606 588
                          const Converter& converter = Converter()) {
607 589
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
608 590
      _writer_bits::MapStorageBase<Arc>* storage =
609 591
        new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
610 592
      _arc_maps.push_back(std::make_pair(caption, storage));
611 593
      return *this;
612 594
    }
613 595

	
614 596
    /// \brief Attribute writing rule
615 597
    ///
616 598
    /// Add an attribute writing rule to the writer.
617 599
    template <typename Value>
618 600
    DigraphWriter& attribute(const std::string& caption, const Value& value) {
619 601
      _writer_bits::ValueStorageBase* storage =
620 602
        new _writer_bits::ValueStorage<Value>(value);
621 603
      _attributes.push_back(std::make_pair(caption, storage));
622 604
      return *this;
623 605
    }
624 606

	
625 607
    /// \brief Attribute writing rule
626 608
    ///
627 609
    /// Add an attribute writing rule with specialized converter to the
628 610
    /// writer.
629 611
    template <typename Value, typename Converter>
630 612
    DigraphWriter& attribute(const std::string& caption, const Value& value,
631 613
                             const Converter& converter = Converter()) {
632 614
      _writer_bits::ValueStorageBase* storage =
633 615
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
634 616
      _attributes.push_back(std::make_pair(caption, storage));
635 617
      return *this;
636 618
    }
637 619

	
638 620
    /// \brief Node writing rule
639 621
    ///
640 622
    /// Add a node writing rule to the writer.
641 623
    DigraphWriter& node(const std::string& caption, const Node& node) {
642 624
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
643 625
      Converter converter(_node_index);
644 626
      _writer_bits::ValueStorageBase* storage =
645 627
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
646 628
      _attributes.push_back(std::make_pair(caption, storage));
647 629
      return *this;
648 630
    }
649 631

	
650 632
    /// \brief Arc writing rule
651 633
    ///
652 634
    /// Add an arc writing rule to writer.
653 635
    DigraphWriter& arc(const std::string& caption, const Arc& arc) {
654 636
      typedef _writer_bits::MapLookUpConverter<Arc> Converter;
655 637
      Converter converter(_arc_index);
656 638
      _writer_bits::ValueStorageBase* storage =
657 639
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
658 640
      _attributes.push_back(std::make_pair(caption, storage));
659 641
      return *this;
660 642
    }
661 643

	
662 644
    /// \name Section captions
663 645
    /// @{
664 646

	
665 647
    /// \brief Add an additional caption to the \c \@nodes section
666 648
    ///
667 649
    /// Add an additional caption to the \c \@nodes section.
668 650
    DigraphWriter& nodes(const std::string& caption) {
669 651
      _nodes_caption = caption;
670 652
      return *this;
671 653
    }
672 654

	
673 655
    /// \brief Add an additional caption to the \c \@arcs section
674 656
    ///
675 657
    /// Add an additional caption to the \c \@arcs section.
676 658
    DigraphWriter& arcs(const std::string& caption) {
677 659
      _arcs_caption = caption;
678 660
      return *this;
679 661
    }
680 662

	
681 663
    /// \brief Add an additional caption to the \c \@attributes section
682 664
    ///
683 665
    /// Add an additional caption to the \c \@attributes section.
684 666
    DigraphWriter& attributes(const std::string& caption) {
685 667
      _attributes_caption = caption;
686 668
      return *this;
687 669
    }
688 670

	
689 671
    /// \name Skipping section
690 672
    /// @{
691 673

	
692 674
    /// \brief Skip writing the node set
693 675
    ///
694 676
    /// The \c \@nodes section will not be written to the stream.
695 677
    DigraphWriter& skipNodes() {
696 678
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
697 679
      _skip_nodes = true;
698 680
      return *this;
699 681
    }
700 682

	
701 683
    /// \brief Skip writing arc set
702 684
    ///
703 685
    /// The \c \@arcs section will not be written to the stream.
704 686
    DigraphWriter& skipArcs() {
705 687
      LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
706 688
      _skip_arcs = true;
707 689
      return *this;
708 690
    }
709 691

	
710 692
    /// @}
711 693

	
712 694
  private:
713 695

	
714 696
    void writeNodes() {
715 697
      _writer_bits::MapStorageBase<Node>* label = 0;
716 698
      for (typename NodeMaps::iterator it = _node_maps.begin();
717 699
           it != _node_maps.end(); ++it) {
718 700
        if (it->first == "label") {
719 701
          label = it->second;
720 702
          break;
721 703
        }
722 704
      }
723 705

	
724 706
      *_os << "@nodes";
725 707
      if (!_nodes_caption.empty()) {
726 708
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
727 709
      }
728 710
      *_os << std::endl;
729 711

	
730 712
      if (label == 0) {
731 713
        *_os << "label" << '\t';
732 714
      }
733 715
      for (typename NodeMaps::iterator it = _node_maps.begin();
734 716
           it != _node_maps.end(); ++it) {
735 717
        _writer_bits::writeToken(*_os, it->first) << '\t';
736 718
      }
737 719
      *_os << std::endl;
738 720

	
739 721
      std::vector<Node> nodes;
740 722
      for (NodeIt n(_digraph); n != INVALID; ++n) {
741 723
        nodes.push_back(n);
742 724
      }
743 725

	
744 726
      if (label == 0) {
745 727
        IdMap<Digraph, Node> id_map(_digraph);
746 728
        _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
747 729
        std::sort(nodes.begin(), nodes.end(), id_less);
748 730
      } else {
749 731
        label->sort(nodes);
750 732
      }
751 733

	
752 734
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
753 735
        Node n = nodes[i];
754 736
        if (label == 0) {
755 737
          std::ostringstream os;
756 738
          os << _digraph.id(n);
757 739
          _writer_bits::writeToken(*_os, os.str());
758 740
          *_os << '\t';
759 741
          _node_index.insert(std::make_pair(n, os.str()));
760 742
        }
761 743
        for (typename NodeMaps::iterator it = _node_maps.begin();
762 744
             it != _node_maps.end(); ++it) {
763 745
          std::string value = it->second->get(n);
764 746
          _writer_bits::writeToken(*_os, value);
765 747
          if (it->first == "label") {
766 748
            _node_index.insert(std::make_pair(n, value));
767 749
          }
768 750
          *_os << '\t';
769 751
        }
770 752
        *_os << std::endl;
771 753
      }
772 754
    }
773 755

	
774 756
    void createNodeIndex() {
775 757
      _writer_bits::MapStorageBase<Node>* label = 0;
776 758
      for (typename NodeMaps::iterator it = _node_maps.begin();
777 759
           it != _node_maps.end(); ++it) {
778 760
        if (it->first == "label") {
779 761
          label = it->second;
780 762
          break;
781 763
        }
782 764
      }
783 765

	
784 766
      if (label == 0) {
785 767
        for (NodeIt n(_digraph); n != INVALID; ++n) {
786 768
          std::ostringstream os;
787 769
          os << _digraph.id(n);
788 770
          _node_index.insert(std::make_pair(n, os.str()));
789 771
        }
790 772
      } else {
791 773
        for (NodeIt n(_digraph); n != INVALID; ++n) {
792 774
          std::string value = label->get(n);
793 775
          _node_index.insert(std::make_pair(n, value));
794 776
        }
795 777
      }
796 778
    }
797 779

	
798 780
    void writeArcs() {
799 781
      _writer_bits::MapStorageBase<Arc>* label = 0;
800 782
      for (typename ArcMaps::iterator it = _arc_maps.begin();
801 783
           it != _arc_maps.end(); ++it) {
802 784
        if (it->first == "label") {
803 785
          label = it->second;
804 786
          break;
805 787
        }
806 788
      }
807 789

	
808 790
      *_os << "@arcs";
809 791
      if (!_arcs_caption.empty()) {
810 792
        _writer_bits::writeToken(*_os << ' ', _arcs_caption);
811 793
      }
812 794
      *_os << std::endl;
813 795

	
814 796
      *_os << '\t' << '\t';
815 797
      if (label == 0) {
816 798
        *_os << "label" << '\t';
817 799
      }
818 800
      for (typename ArcMaps::iterator it = _arc_maps.begin();
819 801
           it != _arc_maps.end(); ++it) {
820 802
        _writer_bits::writeToken(*_os, it->first) << '\t';
821 803
      }
822 804
      *_os << std::endl;
823 805

	
824 806
      std::vector<Arc> arcs;
825 807
      for (ArcIt n(_digraph); n != INVALID; ++n) {
826 808
        arcs.push_back(n);
827 809
      }
828 810

	
829 811
      if (label == 0) {
830 812
        IdMap<Digraph, Arc> id_map(_digraph);
831 813
        _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
832 814
        std::sort(arcs.begin(), arcs.end(), id_less);
833 815
      } else {
834 816
        label->sort(arcs);
835 817
      }
836 818

	
837 819
      for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
838 820
        Arc a = arcs[i];
839 821
        _writer_bits::writeToken(*_os, _node_index.
840 822
                                 find(_digraph.source(a))->second);
841 823
        *_os << '\t';
842 824
        _writer_bits::writeToken(*_os, _node_index.
843 825
                                 find(_digraph.target(a))->second);
844 826
        *_os << '\t';
845 827
        if (label == 0) {
846 828
          std::ostringstream os;
847 829
          os << _digraph.id(a);
848 830
          _writer_bits::writeToken(*_os, os.str());
849 831
          *_os << '\t';
850 832
          _arc_index.insert(std::make_pair(a, os.str()));
851 833
        }
852 834
        for (typename ArcMaps::iterator it = _arc_maps.begin();
853 835
             it != _arc_maps.end(); ++it) {
854 836
          std::string value = it->second->get(a);
855 837
          _writer_bits::writeToken(*_os, value);
856 838
          if (it->first == "label") {
857 839
            _arc_index.insert(std::make_pair(a, value));
858 840
          }
859 841
          *_os << '\t';
860 842
        }
861 843
        *_os << std::endl;
862 844
      }
863 845
    }
864 846

	
865 847
    void createArcIndex() {
866 848
      _writer_bits::MapStorageBase<Arc>* label = 0;
867 849
      for (typename ArcMaps::iterator it = _arc_maps.begin();
868 850
           it != _arc_maps.end(); ++it) {
869 851
        if (it->first == "label") {
870 852
          label = it->second;
871 853
          break;
872 854
        }
873 855
      }
874 856

	
875 857
      if (label == 0) {
876 858
        for (ArcIt a(_digraph); a != INVALID; ++a) {
877 859
          std::ostringstream os;
878 860
          os << _digraph.id(a);
879 861
          _arc_index.insert(std::make_pair(a, os.str()));
880 862
        }
881 863
      } else {
882 864
        for (ArcIt a(_digraph); a != INVALID; ++a) {
883 865
          std::string value = label->get(a);
884 866
          _arc_index.insert(std::make_pair(a, value));
885 867
        }
886 868
      }
887 869
    }
888 870

	
889 871
    void writeAttributes() {
890 872
      if (_attributes.empty()) return;
891 873
      *_os << "@attributes";
892 874
      if (!_attributes_caption.empty()) {
893 875
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
894 876
      }
895 877
      *_os << std::endl;
896 878
      for (typename Attributes::iterator it = _attributes.begin();
897 879
           it != _attributes.end(); ++it) {
898 880
        _writer_bits::writeToken(*_os, it->first) << ' ';
899 881
        _writer_bits::writeToken(*_os, it->second->get());
900 882
        *_os << std::endl;
901 883
      }
902 884
    }
903 885

	
904 886
  public:
905 887

	
906 888
    /// \name Execution of the writer
907 889
    /// @{
908 890

	
909 891
    /// \brief Start the batch processing
910 892
    ///
911 893
    /// This function starts the batch processing.
912 894
    void run() {
913 895
      if (!_skip_nodes) {
914 896
        writeNodes();
915 897
      } else {
916 898
        createNodeIndex();
917 899
      }
918 900
      if (!_skip_arcs) {
919 901
        writeArcs();
920 902
      } else {
921 903
        createArcIndex();
922 904
      }
923 905
      writeAttributes();
924 906
    }
925 907

	
926 908
    /// \brief Give back the stream of the writer
927 909
    ///
928 910
    /// Give back the stream of the writer.
929 911
    std::ostream& ostream() {
930 912
      return *_os;
931 913
    }
932 914

	
933 915
    /// @}
934 916
  };
935 917

	
918
  /// \brief Return a \ref DigraphWriter class
919
  ///
920
  /// This function just returns a \ref DigraphWriter class.
921
  /// \relates DigraphWriter
922
  template <typename Digraph>
923
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
924
                                       std::ostream& os) {
925
    DigraphWriter<Digraph> tmp(digraph, os);
926
    return tmp;
927
  }
928

	
929
  /// \brief Return a \ref DigraphWriter class
930
  ///
931
  /// This function just returns a \ref DigraphWriter class.
932
  /// \relates DigraphWriter
933
  template <typename Digraph>
934
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
935
                                       const std::string& fn) {
936
    DigraphWriter<Digraph> tmp(digraph, fn);
937
    return tmp;
938
  }
939

	
940
  /// \brief Return a \ref DigraphWriter class
941
  ///
942
  /// This function just returns a \ref DigraphWriter class.
943
  /// \relates DigraphWriter
944
  template <typename Digraph>
945
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
946
                                       const char* fn) {
947
    DigraphWriter<Digraph> tmp(digraph, fn);
948
    return tmp;
949
  }
950

	
936 951
  template <typename Graph>
937 952
  class GraphWriter;
938 953

	
939
  /// \brief Return a \ref GraphWriter class
940
  ///
941
  /// This function just returns a \ref GraphWriter class.
942
  /// \relates GraphWriter
943 954
  template <typename Graph>
944 955
  GraphWriter<Graph> graphWriter(const Graph& graph,
945
                                 std::ostream& os = std::cout) {
946
    GraphWriter<Graph> tmp(graph, os);
947
    return tmp;
948
  }
949

	
950
  /// \brief Return a \ref GraphWriter class
951
  ///
952
  /// This function just returns a \ref GraphWriter class.
953
  /// \relates GraphWriter
956
                                 std::ostream& os = std::cout);
954 957
  template <typename Graph>
955
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
956
    GraphWriter<Graph> tmp(graph, fn);
957
    return tmp;
958
  }
959

	
960
  /// \brief Return a \ref GraphWriter class
961
  ///
962
  /// This function just returns a \ref GraphWriter class.
963
  /// \relates GraphWriter
958
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn);
964 959
  template <typename Graph>
965
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
966
    GraphWriter<Graph> tmp(graph, fn);
967
    return tmp;
968
  }
960
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn);
969 961

	
970 962
  /// \ingroup lemon_io
971 963
  ///
972 964
  /// \brief \ref lgf-format "LGF" writer for directed graphs
973 965
  ///
974 966
  /// This utility writes an \ref lgf-format "LGF" file.
975 967
  ///
976 968
  /// It can be used almost the same way as \c DigraphWriter.
977 969
  /// The only difference is that this class can handle edges and
978 970
  /// edge maps as well as arcs and arc maps.
979 971
  ///
980 972
  /// The arc maps are written into the file as two columns, the
981 973
  /// caption of the columns are the name of the map prefixed with \c
982 974
  /// '+' and \c '-'. The arcs are written into the \c \@attributes
983 975
  /// section as a \c '+' or a \c '-' prefix (depends on the direction
984 976
  /// of the arc) and the label of corresponding edge.
985 977
  template <typename _Graph>
986 978
  class GraphWriter {
987 979
  public:
988 980

	
989 981
    typedef _Graph Graph;
990 982
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
991 983

	
992 984
  private:
993 985

	
994 986

	
995 987
    std::ostream* _os;
996 988
    bool local_os;
997 989

	
998 990
    const Graph& _graph;
999 991

	
1000 992
    std::string _nodes_caption;
1001 993
    std::string _edges_caption;
1002 994
    std::string _attributes_caption;
1003 995

	
1004 996
    typedef std::map<Node, std::string> NodeIndex;
1005 997
    NodeIndex _node_index;
1006 998
    typedef std::map<Edge, std::string> EdgeIndex;
1007 999
    EdgeIndex _edge_index;
1008 1000

	
1009 1001
    typedef std::vector<std::pair<std::string,
1010 1002
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
1011 1003
    NodeMaps _node_maps;
1012 1004

	
1013 1005
    typedef std::vector<std::pair<std::string,
1014 1006
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
1015 1007
    EdgeMaps _edge_maps;
1016 1008

	
1017 1009
    typedef std::vector<std::pair<std::string,
1018 1010
      _writer_bits::ValueStorageBase*> > Attributes;
1019 1011
    Attributes _attributes;
1020 1012

	
1021 1013
    bool _skip_nodes;
1022 1014
    bool _skip_edges;
1023 1015

	
1024 1016
  public:
1025 1017

	
1026 1018
    /// \brief Constructor
1027 1019
    ///
1028 1020
    /// Construct a directed graph writer, which writes to the given
1029 1021
    /// output stream.
1030 1022
    GraphWriter(const Graph& graph, std::ostream& os = std::cout)
1031 1023
      : _os(&os), local_os(false), _graph(graph),
1032 1024
        _skip_nodes(false), _skip_edges(false) {}
1033 1025

	
1034 1026
    /// \brief Constructor
1035 1027
    ///
1036 1028
    /// Construct a directed graph writer, which writes to the given
1037 1029
    /// output file.
1038 1030
    GraphWriter(const Graph& graph, const std::string& fn)
1039 1031
      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
1040 1032
        _skip_nodes(false), _skip_edges(false) {
1041 1033
      if (!(*_os)) {
1042 1034
        delete _os;
1043 1035
        throw IoError("Cannot write file", fn);
1044 1036
      }
1045 1037
    }
1046 1038

	
1047 1039
    /// \brief Constructor
1048 1040
    ///
1049 1041
    /// Construct a directed graph writer, which writes to the given
1050 1042
    /// output file.
1051 1043
    GraphWriter(const Graph& graph, const char* fn)
1052 1044
      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
1053 1045
        _skip_nodes(false), _skip_edges(false) {
1054 1046
      if (!(*_os)) {
1055 1047
        delete _os;
1056 1048
        throw IoError("Cannot write file", fn);
1057 1049
      }
1058 1050
    }
1059 1051

	
1060 1052
    /// \brief Destructor
1061 1053
    ~GraphWriter() {
1062 1054
      for (typename NodeMaps::iterator it = _node_maps.begin();
1063 1055
           it != _node_maps.end(); ++it) {
1064 1056
        delete it->second;
1065 1057
      }
1066 1058

	
1067 1059
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1068 1060
           it != _edge_maps.end(); ++it) {
1069 1061
        delete it->second;
1070 1062
      }
1071 1063

	
1072 1064
      for (typename Attributes::iterator it = _attributes.begin();
1073 1065
           it != _attributes.end(); ++it) {
1074 1066
        delete it->second;
1075 1067
      }
1076 1068

	
1077 1069
      if (local_os) {
1078 1070
        delete _os;
1079 1071
      }
1080 1072
    }
1081 1073

	
1082 1074
  private:
1083 1075

	
1084
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1085
                                            std::ostream& os);
1086
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1087
                                            const std::string& fn);
1088
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1089
                                            const char *fn);
1090

	
1076
    template <typename GR>
1077
    friend GraphWriter<GR> graphWriter(const GR& graph,
1078
                                       std::ostream& os);
1079
    template <typename GR>
1080
    friend GraphWriter<GR> graphWriter(const GR& graph,
1081
                                       const std::string& fn);
1082
    template <typename GR>
1083
    friend GraphWriter<GR> graphWriter(const GR& graph,
1084
                                       const char *fn);
1085
    
1091 1086
    GraphWriter(GraphWriter& other)
1092 1087
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
1093 1088
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1094 1089

	
1095 1090
      other._os = 0;
1096 1091
      other.local_os = false;
1097 1092

	
1098 1093
      _node_index.swap(other._node_index);
1099 1094
      _edge_index.swap(other._edge_index);
1100 1095

	
1101 1096
      _node_maps.swap(other._node_maps);
1102 1097
      _edge_maps.swap(other._edge_maps);
1103 1098
      _attributes.swap(other._attributes);
1104 1099

	
1105 1100
      _nodes_caption = other._nodes_caption;
1106 1101
      _edges_caption = other._edges_caption;
1107 1102
      _attributes_caption = other._attributes_caption;
1108 1103
    }
1109 1104

	
1110 1105
    GraphWriter& operator=(const GraphWriter&);
1111 1106

	
1112 1107
  public:
1113 1108

	
1114 1109
    /// \name Writing rules
1115 1110
    /// @{
1116 1111

	
1117 1112
    /// \brief Node map writing rule
1118 1113
    ///
1119 1114
    /// Add a node map writing rule to the writer.
1120 1115
    template <typename Map>
1121 1116
    GraphWriter& nodeMap(const std::string& caption, const Map& map) {
1122 1117
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1123 1118
      _writer_bits::MapStorageBase<Node>* storage =
1124 1119
        new _writer_bits::MapStorage<Node, Map>(map);
1125 1120
      _node_maps.push_back(std::make_pair(caption, storage));
1126 1121
      return *this;
1127 1122
    }
1128 1123

	
1129 1124
    /// \brief Node map writing rule
1130 1125
    ///
1131 1126
    /// Add a node map writing rule with specialized converter to the
1132 1127
    /// writer.
1133 1128
    template <typename Map, typename Converter>
1134 1129
    GraphWriter& nodeMap(const std::string& caption, const Map& map,
1135 1130
                           const Converter& converter = Converter()) {
1136 1131
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1137 1132
      _writer_bits::MapStorageBase<Node>* storage =
1138 1133
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1139 1134
      _node_maps.push_back(std::make_pair(caption, storage));
1140 1135
      return *this;
1141 1136
    }
1142 1137

	
1143 1138
    /// \brief Edge map writing rule
1144 1139
    ///
1145 1140
    /// Add an edge map writing rule to the writer.
1146 1141
    template <typename Map>
1147 1142
    GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1148 1143
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1149 1144
      _writer_bits::MapStorageBase<Edge>* storage =
1150 1145
        new _writer_bits::MapStorage<Edge, Map>(map);
1151 1146
      _edge_maps.push_back(std::make_pair(caption, storage));
1152 1147
      return *this;
1153 1148
    }
1154 1149

	
1155 1150
    /// \brief Edge map writing rule
1156 1151
    ///
1157 1152
    /// Add an edge map writing rule with specialized converter to the
1158 1153
    /// writer.
1159 1154
    template <typename Map, typename Converter>
1160 1155
    GraphWriter& edgeMap(const std::string& caption, const Map& map,
1161 1156
                          const Converter& converter = Converter()) {
1162 1157
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1163 1158
      _writer_bits::MapStorageBase<Edge>* storage =
1164 1159
        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1165 1160
      _edge_maps.push_back(std::make_pair(caption, storage));
1166 1161
      return *this;
1167 1162
    }
1168 1163

	
1169 1164
    /// \brief Arc map writing rule
1170 1165
    ///
1171 1166
    /// Add an arc map writing rule to the writer.
1172 1167
    template <typename Map>
1173 1168
    GraphWriter& arcMap(const std::string& caption, const Map& map) {
1174 1169
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1175 1170
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1176 1171
        new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1177 1172
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1178 1173
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1179 1174
        new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1180 1175
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1181 1176
      return *this;
1182 1177
    }
1183 1178

	
1184 1179
    /// \brief Arc map writing rule
1185 1180
    ///
1186 1181
    /// Add an arc map writing rule with specialized converter to the
1187 1182
    /// writer.
1188 1183
    template <typename Map, typename Converter>
1189 1184
    GraphWriter& arcMap(const std::string& caption, const Map& map,
1190 1185
                          const Converter& converter = Converter()) {
1191 1186
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1192 1187
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1193 1188
        new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1194 1189
        (_graph, map, converter);
1195 1190
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1196 1191
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1197 1192
        new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1198 1193
        (_graph, map, converter);
1199 1194
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1200 1195
      return *this;
1201 1196
    }
1202 1197

	
1203 1198
    /// \brief Attribute writing rule
1204 1199
    ///
1205 1200
    /// Add an attribute writing rule to the writer.
1206 1201
    template <typename Value>
1207 1202
    GraphWriter& attribute(const std::string& caption, const Value& value) {
1208 1203
      _writer_bits::ValueStorageBase* storage =
1209 1204
        new _writer_bits::ValueStorage<Value>(value);
1210 1205
      _attributes.push_back(std::make_pair(caption, storage));
1211 1206
      return *this;
1212 1207
    }
1213 1208

	
1214 1209
    /// \brief Attribute writing rule
1215 1210
    ///
1216 1211
    /// Add an attribute writing rule with specialized converter to the
1217 1212
    /// writer.
1218 1213
    template <typename Value, typename Converter>
1219 1214
    GraphWriter& attribute(const std::string& caption, const Value& value,
1220 1215
                             const Converter& converter = Converter()) {
1221 1216
      _writer_bits::ValueStorageBase* storage =
1222 1217
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1223 1218
      _attributes.push_back(std::make_pair(caption, storage));
1224 1219
      return *this;
1225 1220
    }
1226 1221

	
1227 1222
    /// \brief Node writing rule
1228 1223
    ///
1229 1224
    /// Add a node writing rule to the writer.
1230 1225
    GraphWriter& node(const std::string& caption, const Node& node) {
1231 1226
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
1232 1227
      Converter converter(_node_index);
1233 1228
      _writer_bits::ValueStorageBase* storage =
1234 1229
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1235 1230
      _attributes.push_back(std::make_pair(caption, storage));
1236 1231
      return *this;
1237 1232
    }
1238 1233

	
1239 1234
    /// \brief Edge writing rule
1240 1235
    ///
1241 1236
    /// Add an edge writing rule to writer.
1242 1237
    GraphWriter& edge(const std::string& caption, const Edge& edge) {
1243 1238
      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1244 1239
      Converter converter(_edge_index);
1245 1240
      _writer_bits::ValueStorageBase* storage =
1246 1241
        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1247 1242
      _attributes.push_back(std::make_pair(caption, storage));
1248 1243
      return *this;
1249 1244
    }
1250 1245

	
1251 1246
    /// \brief Arc writing rule
1252 1247
    ///
1253 1248
    /// Add an arc writing rule to writer.
1254 1249
    GraphWriter& arc(const std::string& caption, const Arc& arc) {
1255 1250
      typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1256 1251
      Converter converter(_graph, _edge_index);
1257 1252
      _writer_bits::ValueStorageBase* storage =
1258 1253
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1259 1254
      _attributes.push_back(std::make_pair(caption, storage));
1260 1255
      return *this;
1261 1256
    }
1262 1257

	
1263 1258
    /// \name Section captions
1264 1259
    /// @{
1265 1260

	
1266 1261
    /// \brief Add an additional caption to the \c \@nodes section
1267 1262
    ///
1268 1263
    /// Add an additional caption to the \c \@nodes section.
1269 1264
    GraphWriter& nodes(const std::string& caption) {
1270 1265
      _nodes_caption = caption;
1271 1266
      return *this;
1272 1267
    }
1273 1268

	
1274 1269
    /// \brief Add an additional caption to the \c \@arcs section
1275 1270
    ///
1276 1271
    /// Add an additional caption to the \c \@arcs section.
1277 1272
    GraphWriter& edges(const std::string& caption) {
1278 1273
      _edges_caption = caption;
1279 1274
      return *this;
1280 1275
    }
1281 1276

	
1282 1277
    /// \brief Add an additional caption to the \c \@attributes section
1283 1278
    ///
1284 1279
    /// Add an additional caption to the \c \@attributes section.
1285 1280
    GraphWriter& attributes(const std::string& caption) {
1286 1281
      _attributes_caption = caption;
1287 1282
      return *this;
1288 1283
    }
1289 1284

	
1290 1285
    /// \name Skipping section
1291 1286
    /// @{
1292 1287

	
1293 1288
    /// \brief Skip writing the node set
1294 1289
    ///
1295 1290
    /// The \c \@nodes section will not be written to the stream.
1296 1291
    GraphWriter& skipNodes() {
1297 1292
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1298 1293
      _skip_nodes = true;
1299 1294
      return *this;
1300 1295
    }
1301 1296

	
1302 1297
    /// \brief Skip writing edge set
1303 1298
    ///
1304 1299
    /// The \c \@edges section will not be written to the stream.
1305 1300
    GraphWriter& skipEdges() {
1306 1301
      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1307 1302
      _skip_edges = true;
1308 1303
      return *this;
1309 1304
    }
1310 1305

	
1311 1306
    /// @}
1312 1307

	
1313 1308
  private:
1314 1309

	
1315 1310
    void writeNodes() {
1316 1311
      _writer_bits::MapStorageBase<Node>* label = 0;
1317 1312
      for (typename NodeMaps::iterator it = _node_maps.begin();
1318 1313
           it != _node_maps.end(); ++it) {
1319 1314
        if (it->first == "label") {
1320 1315
          label = it->second;
1321 1316
          break;
1322 1317
        }
1323 1318
      }
1324 1319

	
1325 1320
      *_os << "@nodes";
1326 1321
      if (!_nodes_caption.empty()) {
1327 1322
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1328 1323
      }
1329 1324
      *_os << std::endl;
1330 1325

	
1331 1326
      if (label == 0) {
1332 1327
        *_os << "label" << '\t';
1333 1328
      }
1334 1329
      for (typename NodeMaps::iterator it = _node_maps.begin();
1335 1330
           it != _node_maps.end(); ++it) {
1336 1331
        _writer_bits::writeToken(*_os, it->first) << '\t';
1337 1332
      }
1338 1333
      *_os << std::endl;
1339 1334

	
1340 1335
      std::vector<Node> nodes;
1341 1336
      for (NodeIt n(_graph); n != INVALID; ++n) {
1342 1337
        nodes.push_back(n);
1343 1338
      }
1344 1339

	
1345 1340
      if (label == 0) {
1346 1341
        IdMap<Graph, Node> id_map(_graph);
1347 1342
        _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1348 1343
        std::sort(nodes.begin(), nodes.end(), id_less);
1349 1344
      } else {
1350 1345
        label->sort(nodes);
1351 1346
      }
1352 1347

	
1353 1348
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1354 1349
        Node n = nodes[i];
1355 1350
        if (label == 0) {
1356 1351
          std::ostringstream os;
1357 1352
          os << _graph.id(n);
1358 1353
          _writer_bits::writeToken(*_os, os.str());
1359 1354
          *_os << '\t';
1360 1355
          _node_index.insert(std::make_pair(n, os.str()));
1361 1356
        }
1362 1357
        for (typename NodeMaps::iterator it = _node_maps.begin();
1363 1358
             it != _node_maps.end(); ++it) {
1364 1359
          std::string value = it->second->get(n);
1365 1360
          _writer_bits::writeToken(*_os, value);
1366 1361
          if (it->first == "label") {
1367 1362
            _node_index.insert(std::make_pair(n, value));
1368 1363
          }
1369 1364
          *_os << '\t';
1370 1365
        }
1371 1366
        *_os << std::endl;
1372 1367
      }
1373 1368
    }
1374 1369

	
1375 1370
    void createNodeIndex() {
1376 1371
      _writer_bits::MapStorageBase<Node>* label = 0;
1377 1372
      for (typename NodeMaps::iterator it = _node_maps.begin();
1378 1373
           it != _node_maps.end(); ++it) {
1379 1374
        if (it->first == "label") {
1380 1375
          label = it->second;
1381 1376
          break;
1382 1377
        }
1383 1378
      }
1384 1379

	
1385 1380
      if (label == 0) {
1386 1381
        for (NodeIt n(_graph); n != INVALID; ++n) {
1387 1382
          std::ostringstream os;
1388 1383
          os << _graph.id(n);
1389 1384
          _node_index.insert(std::make_pair(n, os.str()));
1390 1385
        }
1391 1386
      } else {
1392 1387
        for (NodeIt n(_graph); n != INVALID; ++n) {
1393 1388
          std::string value = label->get(n);
1394 1389
          _node_index.insert(std::make_pair(n, value));
1395 1390
        }
1396 1391
      }
1397 1392
    }
1398 1393

	
1399 1394
    void writeEdges() {
1400 1395
      _writer_bits::MapStorageBase<Edge>* label = 0;
1401 1396
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1402 1397
           it != _edge_maps.end(); ++it) {
1403 1398
        if (it->first == "label") {
1404 1399
          label = it->second;
1405 1400
          break;
1406 1401
        }
1407 1402
      }
1408 1403

	
1409 1404
      *_os << "@edges";
1410 1405
      if (!_edges_caption.empty()) {
1411 1406
        _writer_bits::writeToken(*_os << ' ', _edges_caption);
1412 1407
      }
1413 1408
      *_os << std::endl;
1414 1409

	
1415 1410
      *_os << '\t' << '\t';
1416 1411
      if (label == 0) {
1417 1412
        *_os << "label" << '\t';
1418 1413
      }
1419 1414
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1420 1415
           it != _edge_maps.end(); ++it) {
1421 1416
        _writer_bits::writeToken(*_os, it->first) << '\t';
1422 1417
      }
1423 1418
      *_os << std::endl;
1424 1419

	
1425 1420
      std::vector<Edge> edges;
1426 1421
      for (EdgeIt n(_graph); n != INVALID; ++n) {
1427 1422
        edges.push_back(n);
1428 1423
      }
1429 1424

	
1430 1425
      if (label == 0) {
1431 1426
        IdMap<Graph, Edge> id_map(_graph);
1432 1427
        _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1433 1428
        std::sort(edges.begin(), edges.end(), id_less);
1434 1429
      } else {
1435 1430
        label->sort(edges);
1436 1431
      }
1437 1432

	
1438 1433
      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1439 1434
        Edge e = edges[i];
1440 1435
        _writer_bits::writeToken(*_os, _node_index.
1441 1436
                                 find(_graph.u(e))->second);
1442 1437
        *_os << '\t';
1443 1438
        _writer_bits::writeToken(*_os, _node_index.
1444 1439
                                 find(_graph.v(e))->second);
1445 1440
        *_os << '\t';
1446 1441
        if (label == 0) {
1447 1442
          std::ostringstream os;
1448 1443
          os << _graph.id(e);
1449 1444
          _writer_bits::writeToken(*_os, os.str());
1450 1445
          *_os << '\t';
1451 1446
          _edge_index.insert(std::make_pair(e, os.str()));
1452 1447
        }
1453 1448
        for (typename EdgeMaps::iterator it = _edge_maps.begin();
1454 1449
             it != _edge_maps.end(); ++it) {
1455 1450
          std::string value = it->second->get(e);
1456 1451
          _writer_bits::writeToken(*_os, value);
1457 1452
          if (it->first == "label") {
1458 1453
            _edge_index.insert(std::make_pair(e, value));
1459 1454
          }
1460 1455
          *_os << '\t';
1461 1456
        }
1462 1457
        *_os << std::endl;
1463 1458
      }
1464 1459
    }
1465 1460

	
1466 1461
    void createEdgeIndex() {
1467 1462
      _writer_bits::MapStorageBase<Edge>* label = 0;
1468 1463
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1469 1464
           it != _edge_maps.end(); ++it) {
1470 1465
        if (it->first == "label") {
1471 1466
          label = it->second;
1472 1467
          break;
1473 1468
        }
1474 1469
      }
1475 1470

	
1476 1471
      if (label == 0) {
1477 1472
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1478 1473
          std::ostringstream os;
1479 1474
          os << _graph.id(e);
1480 1475
          _edge_index.insert(std::make_pair(e, os.str()));
1481 1476
        }
1482 1477
      } else {
1483 1478
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1484 1479
          std::string value = label->get(e);
1485 1480
          _edge_index.insert(std::make_pair(e, value));
1486 1481
        }
1487 1482
      }
1488 1483
    }
1489 1484

	
1490 1485
    void writeAttributes() {
1491 1486
      if (_attributes.empty()) return;
1492 1487
      *_os << "@attributes";
1493 1488
      if (!_attributes_caption.empty()) {
1494 1489
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1495 1490
      }
1496 1491
      *_os << std::endl;
1497 1492
      for (typename Attributes::iterator it = _attributes.begin();
1498 1493
           it != _attributes.end(); ++it) {
1499 1494
        _writer_bits::writeToken(*_os, it->first) << ' ';
1500 1495
        _writer_bits::writeToken(*_os, it->second->get());
1501 1496
        *_os << std::endl;
1502 1497
      }
1503 1498
    }
1504 1499

	
1505 1500
  public:
1506 1501

	
1507 1502
    /// \name Execution of the writer
1508 1503
    /// @{
1509 1504

	
1510 1505
    /// \brief Start the batch processing
1511 1506
    ///
1512 1507
    /// This function starts the batch processing.
1513 1508
    void run() {
1514 1509
      if (!_skip_nodes) {
1515 1510
        writeNodes();
1516 1511
      } else {
1517 1512
        createNodeIndex();
1518 1513
      }
1519 1514
      if (!_skip_edges) {
1520 1515
        writeEdges();
1521 1516
      } else {
1522 1517
        createEdgeIndex();
1523 1518
      }
1524 1519
      writeAttributes();
1525 1520
    }
1526 1521

	
1527 1522
    /// \brief Give back the stream of the writer
1528 1523
    ///
1529 1524
    /// Give back the stream of the writer
1530 1525
    std::ostream& ostream() {
1531 1526
      return *_os;
1532 1527
    }
1533 1528

	
1534 1529
    /// @}
1535 1530
  };
1536 1531

	
1532
  /// \brief Return a \ref GraphWriter class
1533
  ///
1534
  /// This function just returns a \ref GraphWriter class.
1535
  /// \relates GraphWriter
1536
  template <typename Graph>
1537
  GraphWriter<Graph> graphWriter(const Graph& graph,
1538
                                 std::ostream& os) {
1539
    GraphWriter<Graph> tmp(graph, os);
1540
    return tmp;
1541
  }
1542

	
1543
  /// \brief Return a \ref GraphWriter class
1544
  ///
1545
  /// This function just returns a \ref GraphWriter class.
1546
  /// \relates GraphWriter
1547
  template <typename Graph>
1548
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
1549
    GraphWriter<Graph> tmp(graph, fn);
1550
    return tmp;
1551
  }
1552

	
1553
  /// \brief Return a \ref GraphWriter class
1554
  ///
1555
  /// This function just returns a \ref GraphWriter class.
1556
  /// \relates GraphWriter
1557
  template <typename Graph>
1558
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
1559
    GraphWriter<Graph> tmp(graph, fn);
1560
    return tmp;
1561
  }
1562

	
1537 1563
  class SectionWriter;
1538 1564

	
1539 1565
  SectionWriter sectionWriter(std::istream& is);
1540 1566
  SectionWriter sectionWriter(const std::string& fn);
1541 1567
  SectionWriter sectionWriter(const char* fn);
1542 1568

	
1543 1569
  /// \ingroup lemon_io
1544 1570
  ///
1545 1571
  /// \brief Section writer class
1546 1572
  ///
1547 1573
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
1548 1574
  /// which contain any data in arbitrary format. Such sections can be
1549 1575
  /// written with this class. A writing rule can be added to the
1550 1576
  /// class with two different functions. With the \c sectionLines()
1551 1577
  /// function a generator can write the section line-by-line, while
1552 1578
  /// with the \c sectionStream() member the section can be written to
1553 1579
  /// an output stream.
1554 1580
  class SectionWriter {
1555 1581
  private:
1556 1582

	
1557 1583
    std::ostream* _os;
1558 1584
    bool local_os;
1559 1585

	
1560 1586
    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
1561 1587
    Sections;
1562 1588

	
1563 1589
    Sections _sections;
1564 1590

	
1565 1591
  public:
1566 1592

	
1567 1593
    /// \brief Constructor
1568 1594
    ///
1569 1595
    /// Construct a section writer, which writes to the given output
1570 1596
    /// stream.
1571 1597
    SectionWriter(std::ostream& os)
1572 1598
      : _os(&os), local_os(false) {}
1573 1599

	
1574 1600
    /// \brief Constructor
1575 1601
    ///
1576 1602
    /// Construct a section writer, which writes into the given file.
1577 1603
    SectionWriter(const std::string& fn)
1578 1604
      : _os(new std::ofstream(fn.c_str())), local_os(true) {
1579 1605
      if (!(*_os)) {
1580 1606
        delete _os;
1581 1607
        throw IoError("Cannot write file", fn);
1582 1608
      }
1583 1609
    }
1584 1610

	
1585 1611
    /// \brief Constructor
1586 1612
    ///
1587 1613
    /// Construct a section writer, which writes into the given file.
1588 1614
    SectionWriter(const char* fn)
1589 1615
      : _os(new std::ofstream(fn)), local_os(true) {
1590 1616
      if (!(*_os)) {
1591 1617
        delete _os;
1592 1618
        throw IoError("Cannot write file", fn);
1593 1619
      }
1594 1620
    }
1595 1621

	
1596 1622
    /// \brief Destructor
1597 1623
    ~SectionWriter() {
1598 1624
      for (Sections::iterator it = _sections.begin();
1599 1625
           it != _sections.end(); ++it) {
1600 1626
        delete it->second;
1601 1627
      }
1602 1628

	
1603 1629
      if (local_os) {
1604 1630
        delete _os;
1605 1631
      }
1606 1632

	
1607 1633
    }
1608 1634

	
1609 1635
  private:
1610 1636

	
1611 1637
    friend SectionWriter sectionWriter(std::ostream& os);
1612 1638
    friend SectionWriter sectionWriter(const std::string& fn);
1613 1639
    friend SectionWriter sectionWriter(const char* fn);
1614 1640

	
1615 1641
    SectionWriter(SectionWriter& other)
1616 1642
      : _os(other._os), local_os(other.local_os) {
1617 1643

	
1618 1644
      other._os = 0;
1619 1645
      other.local_os = false;
1620 1646

	
1621 1647
      _sections.swap(other._sections);
1622 1648
    }
1623 1649

	
1624 1650
    SectionWriter& operator=(const SectionWriter&);
1625 1651

	
1626 1652
  public:
1627 1653

	
1628 1654
    /// \name Section writers
1629 1655
    /// @{
1630 1656

	
1631 1657
    /// \brief Add a section writer with line oriented writing
1632 1658
    ///
1633 1659
    /// The first parameter is the type descriptor of the section, the
1634 1660
    /// second is a generator with std::string values. At the writing
1635 1661
    /// process, the returned \c std::string will be written into the
1636 1662
    /// output file until it is an empty string.
1637 1663
    ///
1638 1664
    /// For example, an integer vector is written into a section.
1639 1665
    ///\code
1640 1666
    ///  @numbers
1641 1667
    ///  12 45 23 78
1642 1668
    ///  4 28 38 28
1643 1669
    ///  23 6 16
1644 1670
    ///\endcode
1645 1671
    ///
1646 1672
    /// The generator is implemented as a struct.
1647 1673
    ///\code
1648 1674
    ///  struct NumberSection {
1649 1675
    ///    std::vector<int>::const_iterator _it, _end;
1650 1676
    ///    NumberSection(const std::vector<int>& data)
1651 1677
    ///      : _it(data.begin()), _end(data.end()) {}
1652 1678
    ///    std::string operator()() {
1653 1679
    ///      int rem_in_line = 4;
1654 1680
    ///      std::ostringstream ls;
1655 1681
    ///      while (rem_in_line > 0 && _it != _end) {
1656 1682
    ///        ls << *(_it++) << ' ';
1657 1683
    ///        --rem_in_line;
1658 1684
    ///      }
1659 1685
    ///      return ls.str();
1660 1686
    ///    }
1661 1687
    ///  };
1662 1688
    ///
1663 1689
    ///  // ...
1664 1690
    ///
1665 1691
    ///  writer.sectionLines("numbers", NumberSection(vec));
1666 1692
    ///\endcode
1667 1693
    template <typename Functor>
1668 1694
    SectionWriter& sectionLines(const std::string& type, Functor functor) {
1669 1695
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1670 1696
      _sections.push_back(std::make_pair(type,
1671 1697
        new _writer_bits::LineSection<Functor>(functor)));
1672 1698
      return *this;
1673 1699
    }
1674 1700

	
1675 1701

	
1676 1702
    /// \brief Add a section writer with stream oriented writing
1677 1703
    ///
1678 1704
    /// The first parameter is the type of the section, the second is
1679 1705
    /// a functor, which takes a \c std::ostream& parameter. The
1680 1706
    /// functor writes the section to the output stream.
1681 1707
    /// \warning The last line must be closed with end-line character.
1682 1708
    template <typename Functor>
1683 1709
    SectionWriter& sectionStream(const std::string& type, Functor functor) {
1684 1710
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1685 1711
      _sections.push_back(std::make_pair(type,
1686 1712
         new _writer_bits::StreamSection<Functor>(functor)));
1687 1713
      return *this;
1688 1714
    }
1689 1715

	
1690 1716
    /// @}
1691 1717

	
1692 1718
  public:
1693 1719

	
1694 1720

	
1695 1721
    /// \name Execution of the writer
1696 1722
    /// @{
1697 1723

	
1698 1724
    /// \brief Start the batch processing
1699 1725
    ///
1700 1726
    /// This function starts the batch processing.
1701 1727
    void run() {
1702 1728

	
1703 1729
      LEMON_ASSERT(_os != 0, "This writer is assigned to an other writer");
1704 1730

	
1705 1731
      for (Sections::iterator it = _sections.begin();
1706 1732
           it != _sections.end(); ++it) {
1707 1733
        (*_os) << '@' << it->first << std::endl;
1708 1734
        it->second->process(*_os);
1709 1735
      }
1710 1736
    }
1711 1737

	
1712 1738
    /// \brief Give back the stream of the writer
1713 1739
    ///
1714 1740
    /// Returns the stream of the writer
1715 1741
    std::ostream& ostream() {
1716 1742
      return *_os;
1717 1743
    }
1718 1744

	
1719 1745
    /// @}
1720 1746

	
1721 1747
  };
1722 1748

	
1723 1749
  /// \brief Return a \ref SectionWriter class
1724 1750
  ///
1725 1751
  /// This function just returns a \ref SectionWriter class.
1726 1752
  /// \relates SectionWriter
1727 1753
  inline SectionWriter sectionWriter(std::ostream& os) {
1728 1754
    SectionWriter tmp(os);
1729 1755
    return tmp;
1730 1756
  }
1731 1757

	
1732 1758
  /// \brief Return a \ref SectionWriter class
1733 1759
  ///
1734 1760
  /// This function just returns a \ref SectionWriter class.
1735 1761
  /// \relates SectionWriter
1736 1762
  inline SectionWriter sectionWriter(const std::string& fn) {
1737 1763
    SectionWriter tmp(fn);
1738 1764
    return tmp;
1739 1765
  }
1740 1766

	
1741 1767
  /// \brief Return a \ref SectionWriter class
1742 1768
  ///
1743 1769
  /// This function just returns a \ref SectionWriter class.
1744 1770
  /// \relates SectionWriter
1745 1771
  inline SectionWriter sectionWriter(const char* fn) {
1746 1772
    SectionWriter tmp(fn);
1747 1773
    return tmp;
1748 1774
  }
1749 1775
}
1750 1776

	
1751 1777
#endif
Ignore white space 6 line context
... ...
@@ -164,923 +164,939 @@
164 164
    void eraseFront() {
165 165
      if (!head.empty()) {
166 166
        head.pop_back();
167 167
      } else {
168 168
        head.clear();
169 169
        int halfsize = tail.size() / 2;
170 170
        head.resize(halfsize);
171 171
        std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
172 172
                  head.rbegin());
173 173
        std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
174 174
        tail.resize(tail.size() - halfsize - 1);
175 175
      }
176 176
    }
177 177

	
178 178
    /// \brief The last arc of the path
179 179
    const Arc& back() const {
180 180
      return tail.empty() ? head.front() : tail.back();
181 181
    }
182 182

	
183 183
    /// \brief Add a new arc behind the current path
184 184
    void addBack(const Arc& arc) {
185 185
      tail.push_back(arc);
186 186
    }
187 187

	
188 188
    /// \brief Erase the last arc of the path
189 189
    void eraseBack() {
190 190
      if (!tail.empty()) {
191 191
        tail.pop_back();
192 192
      } else {
193 193
        int halfsize = head.size() / 2;
194 194
        tail.resize(halfsize);
195 195
        std::copy(head.begin() + 1, head.begin() + halfsize + 1,
196 196
                  tail.rbegin());
197 197
        std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
198 198
        head.resize(head.size() - halfsize - 1);
199 199
      }
200 200
    }
201 201

	
202 202
    typedef True BuildTag;
203 203

	
204 204
    template <typename CPath>
205 205
    void build(const CPath& path) {
206 206
      int len = path.length();
207 207
      tail.reserve(len);
208 208
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
209 209
        tail.push_back(it);
210 210
      }
211 211
    }
212 212

	
213 213
    template <typename CPath>
214 214
    void buildRev(const CPath& path) {
215 215
      int len = path.length();
216 216
      head.reserve(len);
217 217
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
218 218
        head.push_back(it);
219 219
      }
220 220
    }
221 221

	
222 222
  protected:
223 223
    typedef std::vector<Arc> Container;
224 224
    Container head, tail;
225 225

	
226 226
  };
227 227

	
228 228
  /// \brief A structure for representing directed paths in a digraph.
229 229
  ///
230 230
  /// A structure for representing directed path in a digraph.
231 231
  /// \tparam _Digraph The digraph type in which the path is.
232 232
  ///
233 233
  /// In a sense, the path can be treated as a list of arcs. The
234 234
  /// lemon path type stores just this list. As a consequence it
235 235
  /// cannot enumerate the nodes in the path and the zero length paths
236 236
  /// cannot store the source.
237 237
  ///
238 238
  /// This implementation is a just back insertable and erasable path
239 239
  /// type. It can be indexed in O(1) time. The back insertion and
240 240
  /// erasure is amortized O(1) time. This implementation is faster
241 241
  /// then the \c Path type because it use just one vector for the
242 242
  /// arcs.
243 243
  template <typename _Digraph>
244 244
  class SimplePath {
245 245
  public:
246 246

	
247 247
    typedef _Digraph Digraph;
248 248
    typedef typename Digraph::Arc Arc;
249 249

	
250 250
    /// \brief Default constructor
251 251
    ///
252 252
    /// Default constructor
253 253
    SimplePath() {}
254 254

	
255 255
    /// \brief Template copy constructor
256 256
    ///
257 257
    /// This path can be initialized with any other path type. It just
258 258
    /// makes a copy of the given path.
259 259
    template <typename CPath>
260 260
    SimplePath(const CPath& cpath) {
261 261
      copyPath(*this, cpath);
262 262
    }
263 263

	
264 264
    /// \brief Template copy assignment
265 265
    ///
266 266
    /// This path can be initialized with any other path type. It just
267 267
    /// makes a copy of the given path.
268 268
    template <typename CPath>
269 269
    SimplePath& operator=(const CPath& cpath) {
270 270
      copyPath(*this, cpath);
271 271
      return *this;
272 272
    }
273 273

	
274 274
    /// \brief Iterator class to iterate on the arcs of the paths
275 275
    ///
276 276
    /// This class is used to iterate on the arcs of the paths
277 277
    ///
278 278
    /// Of course it converts to Digraph::Arc
279 279
    class ArcIt {
280 280
      friend class SimplePath;
281 281
    public:
282 282
      /// Default constructor
283 283
      ArcIt() {}
284 284
      /// Invalid constructor
285 285
      ArcIt(Invalid) : path(0), idx(-1) {}
286 286
      /// \brief Initializate the constructor to the first arc of path
287 287
      ArcIt(const SimplePath &_path)
288 288
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
289 289

	
290 290
    private:
291 291

	
292 292
      /// Constructor with starting point
293 293
      ArcIt(const SimplePath &_path, int _idx)
294 294
        : idx(_idx), path(&_path) {}
295 295

	
296 296
    public:
297 297

	
298 298
      ///Conversion to Digraph::Arc
299 299
      operator const Arc&() const {
300 300
        return path->nth(idx);
301 301
      }
302 302

	
303 303
      /// Next arc
304 304
      ArcIt& operator++() {
305 305
        ++idx;
306 306
        if (idx >= path->length()) idx = -1;
307 307
        return *this;
308 308
      }
309 309

	
310 310
      /// Comparison operator
311 311
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
312 312
      /// Comparison operator
313 313
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
314 314
      /// Comparison operator
315 315
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
316 316

	
317 317
    private:
318 318
      const SimplePath *path;
319 319
      int idx;
320 320
    };
321 321

	
322 322
    /// \brief Length of the path.
323 323
    int length() const { return data.size(); }
324 324
    /// \brief Return true if the path is empty.
325 325
    bool empty() const { return data.empty(); }
326 326

	
327 327
    /// \brief Reset the path to an empty one.
328 328
    void clear() { data.clear(); }
329 329

	
330 330
    /// \brief The nth arc.
331 331
    ///
332 332
    /// \pre n is in the [0..length() - 1] range
333 333
    const Arc& nth(int n) const {
334 334
      return data[n];
335 335
    }
336 336

	
337 337
    /// \brief  Initializes arc iterator to point to the nth arc.
338 338
    ArcIt nthIt(int n) const {
339 339
      return ArcIt(*this, n);
340 340
    }
341 341

	
342 342
    /// \brief The first arc of the path.
343 343
    const Arc& front() const {
344 344
      return data.front();
345 345
    }
346 346

	
347 347
    /// \brief The last arc of the path.
348 348
    const Arc& back() const {
349 349
      return data.back();
350 350
    }
351 351

	
352 352
    /// \brief Add a new arc behind the current path.
353 353
    void addBack(const Arc& arc) {
354 354
      data.push_back(arc);
355 355
    }
356 356

	
357 357
    /// \brief Erase the last arc of the path
358 358
    void eraseBack() {
359 359
      data.pop_back();
360 360
    }
361 361

	
362 362
    typedef True BuildTag;
363 363

	
364 364
    template <typename CPath>
365 365
    void build(const CPath& path) {
366 366
      int len = path.length();
367 367
      data.resize(len);
368 368
      int index = 0;
369 369
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
370 370
        data[index] = it;;
371 371
        ++index;
372 372
      }
373 373
    }
374 374

	
375 375
    template <typename CPath>
376 376
    void buildRev(const CPath& path) {
377 377
      int len = path.length();
378 378
      data.resize(len);
379 379
      int index = len;
380 380
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
381 381
        --index;
382 382
        data[index] = it;;
383 383
      }
384 384
    }
385 385

	
386 386
  protected:
387 387
    typedef std::vector<Arc> Container;
388 388
    Container data;
389 389

	
390 390
  };
391 391

	
392 392
  /// \brief A structure for representing directed paths in a digraph.
393 393
  ///
394 394
  /// A structure for representing directed path in a digraph.
395 395
  /// \tparam _Digraph The digraph type in which the path is.
396 396
  ///
397 397
  /// In a sense, the path can be treated as a list of arcs. The
398 398
  /// lemon path type stores just this list. As a consequence it
399 399
  /// cannot enumerate the nodes in the path and the zero length paths
400 400
  /// cannot store the source.
401 401
  ///
402 402
  /// This implementation is a back and front insertable and erasable
403 403
  /// path type. It can be indexed in O(k) time, where k is the rank
404 404
  /// of the arc in the path. The length can be computed in O(n)
405 405
  /// time. The front and back insertion and erasure is O(1) time
406 406
  /// and it can be splited and spliced in O(1) time.
407 407
  template <typename _Digraph>
408 408
  class ListPath {
409 409
  public:
410 410

	
411 411
    typedef _Digraph Digraph;
412 412
    typedef typename Digraph::Arc Arc;
413 413

	
414 414
  protected:
415 415

	
416 416
    // the std::list<> is incompatible
417 417
    // hard to create invalid iterator
418 418
    struct Node {
419 419
      Arc arc;
420 420
      Node *next, *prev;
421 421
    };
422 422

	
423 423
    Node *first, *last;
424 424

	
425 425
    std::allocator<Node> alloc;
426 426

	
427 427
  public:
428 428

	
429 429
    /// \brief Default constructor
430 430
    ///
431 431
    /// Default constructor
432 432
    ListPath() : first(0), last(0) {}
433 433

	
434 434
    /// \brief Template copy constructor
435 435
    ///
436 436
    /// This path can be initialized with any other path type. It just
437 437
    /// makes a copy of the given path.
438 438
    template <typename CPath>
439 439
    ListPath(const CPath& cpath) : first(0), last(0) {
440 440
      copyPath(*this, cpath);
441 441
    }
442 442

	
443 443
    /// \brief Destructor of the path
444 444
    ///
445 445
    /// Destructor of the path
446 446
    ~ListPath() {
447 447
      clear();
448 448
    }
449 449

	
450 450
    /// \brief Template copy assignment
451 451
    ///
452 452
    /// This path can be initialized with any other path type. It just
453 453
    /// makes a copy of the given path.
454 454
    template <typename CPath>
455 455
    ListPath& operator=(const CPath& cpath) {
456 456
      copyPath(*this, cpath);
457 457
      return *this;
458 458
    }
459 459

	
460 460
    /// \brief Iterator class to iterate on the arcs of the paths
461 461
    ///
462 462
    /// This class is used to iterate on the arcs of the paths
463 463
    ///
464 464
    /// Of course it converts to Digraph::Arc
465 465
    class ArcIt {
466 466
      friend class ListPath;
467 467
    public:
468 468
      /// Default constructor
469 469
      ArcIt() {}
470 470
      /// Invalid constructor
471 471
      ArcIt(Invalid) : path(0), node(0) {}
472 472
      /// \brief Initializate the constructor to the first arc of path
473 473
      ArcIt(const ListPath &_path)
474 474
        : path(&_path), node(_path.first) {}
475 475

	
476 476
    protected:
477 477

	
478 478
      ArcIt(const ListPath &_path, Node *_node)
479 479
        : path(&_path), node(_node) {}
480 480

	
481 481

	
482 482
    public:
483 483

	
484 484
      ///Conversion to Digraph::Arc
485 485
      operator const Arc&() const {
486 486
        return node->arc;
487 487
      }
488 488

	
489 489
      /// Next arc
490 490
      ArcIt& operator++() {
491 491
        node = node->next;
492 492
        return *this;
493 493
      }
494 494

	
495 495
      /// Comparison operator
496 496
      bool operator==(const ArcIt& e) const { return node==e.node; }
497 497
      /// Comparison operator
498 498
      bool operator!=(const ArcIt& e) const { return node!=e.node; }
499 499
      /// Comparison operator
500 500
      bool operator<(const ArcIt& e) const { return node<e.node; }
501 501

	
502 502
    private:
503 503
      const ListPath *path;
504 504
      Node *node;
505 505
    };
506 506

	
507 507
    /// \brief The nth arc.
508 508
    ///
509 509
    /// This function looks for the nth arc in O(n) time.
510 510
    /// \pre n is in the [0..length() - 1] range
511 511
    const Arc& nth(int n) const {
512 512
      Node *node = first;
513 513
      for (int i = 0; i < n; ++i) {
514 514
        node = node->next;
515 515
      }
516 516
      return node->arc;
517 517
    }
518 518

	
519 519
    /// \brief Initializes arc iterator to point to the nth arc.
520 520
    ArcIt nthIt(int n) const {
521 521
      Node *node = first;
522 522
      for (int i = 0; i < n; ++i) {
523 523
        node = node->next;
524 524
      }
525 525
      return ArcIt(*this, node);
526 526
    }
527 527

	
528 528
    /// \brief Length of the path.
529 529
    int length() const {
530 530
      int len = 0;
531 531
      Node *node = first;
532 532
      while (node != 0) {
533 533
        node = node->next;
534 534
        ++len;
535 535
      }
536 536
      return len;
537 537
    }
538 538

	
539 539
    /// \brief Return true if the path is empty.
540 540
    bool empty() const { return first == 0; }
541 541

	
542 542
    /// \brief Reset the path to an empty one.
543 543
    void clear() {
544 544
      while (first != 0) {
545 545
        last = first->next;
546 546
        alloc.destroy(first);
547 547
        alloc.deallocate(first, 1);
548 548
        first = last;
549 549
      }
550 550
    }
551 551

	
552 552
    /// \brief The first arc of the path
553 553
    const Arc& front() const {
554 554
      return first->arc;
555 555
    }
556 556

	
557 557
    /// \brief Add a new arc before the current path
558 558
    void addFront(const Arc& arc) {
559 559
      Node *node = alloc.allocate(1);
560 560
      alloc.construct(node, Node());
561 561
      node->prev = 0;
562 562
      node->next = first;
563 563
      node->arc = arc;
564 564
      if (first) {
565 565
        first->prev = node;
566 566
        first = node;
567 567
      } else {
568 568
        first = last = node;
569 569
      }
570 570
    }
571 571

	
572 572
    /// \brief Erase the first arc of the path
573 573
    void eraseFront() {
574 574
      Node *node = first;
575 575
      first = first->next;
576 576
      if (first) {
577 577
        first->prev = 0;
578 578
      } else {
579 579
        last = 0;
580 580
      }
581 581
      alloc.destroy(node);
582 582
      alloc.deallocate(node, 1);
583 583
    }
584 584

	
585 585
    /// \brief The last arc of the path.
586 586
    const Arc& back() const {
587 587
      return last->arc;
588 588
    }
589 589

	
590 590
    /// \brief Add a new arc behind the current path.
591 591
    void addBack(const Arc& arc) {
592 592
      Node *node = alloc.allocate(1);
593 593
      alloc.construct(node, Node());
594 594
      node->next = 0;
595 595
      node->prev = last;
596 596
      node->arc = arc;
597 597
      if (last) {
598 598
        last->next = node;
599 599
        last = node;
600 600
      } else {
601 601
        last = first = node;
602 602
      }
603 603
    }
604 604

	
605 605
    /// \brief Erase the last arc of the path
606 606
    void eraseBack() {
607 607
      Node *node = last;
608 608
      last = last->prev;
609 609
      if (last) {
610 610
        last->next = 0;
611 611
      } else {
612 612
        first = 0;
613 613
      }
614 614
      alloc.destroy(node);
615 615
      alloc.deallocate(node, 1);
616 616
    }
617 617

	
618 618
    /// \brief Splice a path to the back of the current path.
619 619
    ///
620 620
    /// It splices \c tpath to the back of the current path and \c
621 621
    /// tpath becomes empty. The time complexity of this function is
622 622
    /// O(1).
623 623
    void spliceBack(ListPath& tpath) {
624 624
      if (first) {
625 625
        if (tpath.first) {
626 626
          last->next = tpath.first;
627 627
          tpath.first->prev = last;
628 628
          last = tpath.last;
629 629
        }
630 630
      } else {
631 631
        first = tpath.first;
632 632
        last = tpath.last;
633 633
      }
634 634
      tpath.first = tpath.last = 0;
635 635
    }
636 636

	
637 637
    /// \brief Splice a path to the front of the current path.
638 638
    ///
639 639
    /// It splices \c tpath before the current path and \c tpath
640 640
    /// becomes empty. The time complexity of this function
641 641
    /// is O(1).
642 642
    void spliceFront(ListPath& tpath) {
643 643
      if (first) {
644 644
        if (tpath.first) {
645 645
          first->prev = tpath.last;
646 646
          tpath.last->next = first;
647 647
          first = tpath.first;
648 648
        }
649 649
      } else {
650 650
        first = tpath.first;
651 651
        last = tpath.last;
652 652
      }
653 653
      tpath.first = tpath.last = 0;
654 654
    }
655 655

	
656 656
    /// \brief Splice a path into the current path.
657 657
    ///
658 658
    /// It splices the \c tpath into the current path before the
659 659
    /// position of \c it iterator and \c tpath becomes empty. The
660 660
    /// time complexity of this function is O(1). If the \c it is
661 661
    /// \c INVALID then it will splice behind the current path.
662 662
    void splice(ArcIt it, ListPath& tpath) {
663 663
      if (it.node) {
664 664
        if (tpath.first) {
665 665
          tpath.first->prev = it.node->prev;
666 666
          if (it.node->prev) {
667 667
            it.node->prev->next = tpath.first;
668 668
          } else {
669 669
            first = tpath.first;
670 670
          }
671 671
          it.node->prev = tpath.last;
672 672
          tpath.last->next = it.node;
673 673
        }
674 674
      } else {
675 675
        if (first) {
676 676
          if (tpath.first) {
677 677
            last->next = tpath.first;
678 678
            tpath.first->prev = last;
679 679
            last = tpath.last;
680 680
          }
681 681
        } else {
682 682
          first = tpath.first;
683 683
          last = tpath.last;
684 684
        }
685 685
      }
686 686
      tpath.first = tpath.last = 0;
687 687
    }
688 688

	
689 689
    /// \brief Split the current path.
690 690
    ///
691 691
    /// It splits the current path into two parts. The part before
692 692
    /// the iterator \c it will remain in the current path and the part
693 693
    /// starting with
694 694
    /// \c it will put into \c tpath. If \c tpath have arcs
695 695
    /// before the operation they are removed first.  The time
696 696
    /// complexity of this function is O(1) plus the the time of emtying
697 697
    /// \c tpath. If \c it is \c INVALID then it just clears \c tpath
698 698
    void split(ArcIt it, ListPath& tpath) {
699 699
      tpath.clear();
700 700
      if (it.node) {
701 701
        tpath.first = it.node;
702 702
        tpath.last = last;
703 703
        if (it.node->prev) {
704 704
          last = it.node->prev;
705 705
          last->next = 0;
706 706
        } else {
707 707
          first = last = 0;
708 708
        }
709 709
        it.node->prev = 0;
710 710
      }
711 711
    }
712 712

	
713 713

	
714 714
    typedef True BuildTag;
715 715

	
716 716
    template <typename CPath>
717 717
    void build(const CPath& path) {
718 718
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
719 719
        addBack(it);
720 720
      }
721 721
    }
722 722

	
723 723
    template <typename CPath>
724 724
    void buildRev(const CPath& path) {
725 725
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
726 726
        addFront(it);
727 727
      }
728 728
    }
729 729

	
730 730
  };
731 731

	
732 732
  /// \brief A structure for representing directed paths in a digraph.
733 733
  ///
734 734
  /// A structure for representing directed path in a digraph.
735 735
  /// \tparam _Digraph The digraph type in which the path is.
736 736
  ///
737 737
  /// In a sense, the path can be treated as a list of arcs. The
738 738
  /// lemon path type stores just this list. As a consequence it
739 739
  /// cannot enumerate the nodes in the path and the source node of
740 740
  /// a zero length path is undefined.
741 741
  ///
742 742
  /// This implementation is completly static, i.e. it can be copy constucted
743 743
  /// or copy assigned from another path, but otherwise it cannot be
744 744
  /// modified.
745 745
  ///
746 746
  /// Being the the most memory efficient path type in LEMON,
747 747
  /// it is intented to be
748 748
  /// used when you want to store a large number of paths.
749 749
  template <typename _Digraph>
750 750
  class StaticPath {
751 751
  public:
752 752

	
753 753
    typedef _Digraph Digraph;
754 754
    typedef typename Digraph::Arc Arc;
755 755

	
756 756
    /// \brief Default constructor
757 757
    ///
758 758
    /// Default constructor
759 759
    StaticPath() : len(0), arcs(0) {}
760 760

	
761 761
    /// \brief Template copy constructor
762 762
    ///
763 763
    /// This path can be initialized from any other path type.
764 764
    template <typename CPath>
765 765
    StaticPath(const CPath& cpath) : arcs(0) {
766 766
      copyPath(*this, cpath);
767 767
    }
768 768

	
769 769
    /// \brief Destructor of the path
770 770
    ///
771 771
    /// Destructor of the path
772 772
    ~StaticPath() {
773 773
      if (arcs) delete[] arcs;
774 774
    }
775 775

	
776 776
    /// \brief Template copy assignment
777 777
    ///
778 778
    /// This path can be made equal to any other path type. It simply
779 779
    /// makes a copy of the given path.
780 780
    template <typename CPath>
781 781
    StaticPath& operator=(const CPath& cpath) {
782 782
      copyPath(*this, cpath);
783 783
      return *this;
784 784
    }
785 785

	
786 786
    /// \brief Iterator class to iterate on the arcs of the paths
787 787
    ///
788 788
    /// This class is used to iterate on the arcs of the paths
789 789
    ///
790 790
    /// Of course it converts to Digraph::Arc
791 791
    class ArcIt {
792 792
      friend class StaticPath;
793 793
    public:
794 794
      /// Default constructor
795 795
      ArcIt() {}
796 796
      /// Invalid constructor
797 797
      ArcIt(Invalid) : path(0), idx(-1) {}
798 798
      /// Initializate the constructor to the first arc of path
799 799
      ArcIt(const StaticPath &_path)
800 800
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
801 801

	
802 802
    private:
803 803

	
804 804
      /// Constructor with starting point
805 805
      ArcIt(const StaticPath &_path, int _idx)
806 806
        : idx(_idx), path(&_path) {}
807 807

	
808 808
    public:
809 809

	
810 810
      ///Conversion to Digraph::Arc
811 811
      operator const Arc&() const {
812 812
        return path->nth(idx);
813 813
      }
814 814

	
815 815
      /// Next arc
816 816
      ArcIt& operator++() {
817 817
        ++idx;
818 818
        if (idx >= path->length()) idx = -1;
819 819
        return *this;
820 820
      }
821 821

	
822 822
      /// Comparison operator
823 823
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
824 824
      /// Comparison operator
825 825
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
826 826
      /// Comparison operator
827 827
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
828 828

	
829 829
    private:
830 830
      const StaticPath *path;
831 831
      int idx;
832 832
    };
833 833

	
834 834
    /// \brief The nth arc.
835 835
    ///
836 836
    /// \pre n is in the [0..length() - 1] range
837 837
    const Arc& nth(int n) const {
838 838
      return arcs[n];
839 839
    }
840 840

	
841 841
    /// \brief The arc iterator pointing to the nth arc.
842 842
    ArcIt nthIt(int n) const {
843 843
      return ArcIt(*this, n);
844 844
    }
845 845

	
846 846
    /// \brief The length of the path.
847 847
    int length() const { return len; }
848 848

	
849 849
    /// \brief Return true when the path is empty.
850 850
    int empty() const { return len == 0; }
851 851

	
852 852
    /// \brief Erase all arcs in the digraph.
853 853
    void clear() {
854 854
      len = 0;
855 855
      if (arcs) delete[] arcs;
856 856
      arcs = 0;
857 857
    }
858 858

	
859 859
    /// \brief The first arc of the path.
860 860
    const Arc& front() const {
861 861
      return arcs[0];
862 862
    }
863 863

	
864 864
    /// \brief The last arc of the path.
865 865
    const Arc& back() const {
866 866
      return arcs[len - 1];
867 867
    }
868 868

	
869 869

	
870 870
    typedef True BuildTag;
871 871

	
872 872
    template <typename CPath>
873 873
    void build(const CPath& path) {
874 874
      len = path.length();
875 875
      arcs = new Arc[len];
876 876
      int index = 0;
877 877
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
878 878
        arcs[index] = it;
879 879
        ++index;
880 880
      }
881 881
    }
882 882

	
883 883
    template <typename CPath>
884 884
    void buildRev(const CPath& path) {
885 885
      len = path.length();
886 886
      arcs = new Arc[len];
887 887
      int index = len;
888 888
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
889 889
        --index;
890 890
        arcs[index] = it;
891 891
      }
892 892
    }
893 893

	
894 894
  private:
895 895
    int len;
896 896
    Arc* arcs;
897 897
  };
898 898

	
899 899
  ///////////////////////////////////////////////////////////////////////
900 900
  // Additional utilities
901 901
  ///////////////////////////////////////////////////////////////////////
902 902

	
903 903
  namespace _path_bits {
904 904

	
905 905
    template <typename Path, typename Enable = void>
906 906
    struct RevPathTagIndicator {
907 907
      static const bool value = false;
908 908
    };
909 909

	
910 910
    template <typename Path>
911 911
    struct RevPathTagIndicator<
912 912
      Path,
913 913
      typename enable_if<typename Path::RevPathTag, void>::type
914 914
      > {
915 915
      static const bool value = true;
916 916
    };
917 917

	
918 918
    template <typename Path, typename Enable = void>
919 919
    struct BuildTagIndicator {
920 920
      static const bool value = false;
921 921
    };
922 922

	
923 923
    template <typename Path>
924 924
    struct BuildTagIndicator<
925 925
      Path,
926 926
      typename enable_if<typename Path::BuildTag, void>::type
927 927
    > {
928 928
      static const bool value = true;
929 929
    };
930 930

	
931 931
    template <typename Target, typename Source,
932
              bool buildEnable = BuildTagIndicator<Target>::value,
933
              bool revEnable = RevPathTagIndicator<Source>::value>
934
    struct PathCopySelector {
932
              bool buildEnable = BuildTagIndicator<Target>::value>
933
    struct PathCopySelectorForward {
935 934
      static void copy(Target& target, const Source& source) {
936 935
        target.clear();
937 936
        for (typename Source::ArcIt it(source); it != INVALID; ++it) {
938 937
          target.addBack(it);
939 938
        }
940 939
      }
941 940
    };
942 941

	
943 942
    template <typename Target, typename Source>
944
    struct PathCopySelector<Target, Source, false, true> {
943
    struct PathCopySelectorForward<Target, Source, true> {
944
      static void copy(Target& target, const Source& source) {
945
        target.clear();
946
        target.build(source);
947
      }
948
    };
949

	
950
    template <typename Target, typename Source,
951
              bool buildEnable = BuildTagIndicator<Target>::value>
952
    struct PathCopySelectorBackward {
945 953
      static void copy(Target& target, const Source& source) {
946 954
        target.clear();
947 955
        for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
948 956
          target.addFront(it);
949 957
        }
950 958
      }
951 959
    };
952 960

	
953 961
    template <typename Target, typename Source>
954
    struct PathCopySelector<Target, Source, true, false> {
955
      static void copy(Target& target, const Source& source) {
956
        target.clear();
957
        target.build(source);
958
      }
959
    };
960

	
961
    template <typename Target, typename Source>
962
    struct PathCopySelector<Target, Source, true, true> {
962
    struct PathCopySelectorBackward<Target, Source, true> {
963 963
      static void copy(Target& target, const Source& source) {
964 964
        target.clear();
965 965
        target.buildRev(source);
966 966
      }
967 967
    };
968 968

	
969
    
970
    template <typename Target, typename Source,
971
              bool revEnable = RevPathTagIndicator<Source>::value>
972
    struct PathCopySelector {
973
      static void copy(Target& target, const Source& source) {
974
        PathCopySelectorForward<Target, Source>::copy(target, source);
975
      }      
976
    };
977

	
978
    template <typename Target, typename Source>
979
    struct PathCopySelector<Target, Source, true> {
980
      static void copy(Target& target, const Source& source) {
981
        PathCopySelectorBackward<Target, Source>::copy(target, source);
982
      }      
983
    };
984

	
969 985
  }
970 986

	
971 987

	
972 988
  /// \brief Make a copy of a path.
973 989
  ///
974 990
  ///  This function makes a copy of a path.
975 991
  template <typename Target, typename Source>
976 992
  void copyPath(Target& target, const Source& source) {
977 993
    checkConcept<concepts::PathDumper<typename Source::Digraph>, Source>();
978 994
    _path_bits::PathCopySelector<Target, Source>::copy(target, source);
979 995
  }
980 996

	
981 997
  /// \brief Check the consistency of a path.
982 998
  ///
983 999
  /// This function checks that the target of each arc is the same
984 1000
  /// as the source of the next one.
985 1001
  ///
986 1002
  template <typename Digraph, typename Path>
987 1003
  bool checkPath(const Digraph& digraph, const Path& path) {
988 1004
    typename Path::ArcIt it(path);
989 1005
    if (it == INVALID) return true;
990 1006
    typename Digraph::Node node = digraph.target(it);
991 1007
    ++it;
992 1008
    while (it != INVALID) {
993 1009
      if (digraph.source(it) != node) return false;
994 1010
      node = digraph.target(it);
995 1011
      ++it;
996 1012
    }
997 1013
    return true;
998 1014
  }
999 1015

	
1000 1016
  /// \brief The source of a path
1001 1017
  ///
1002 1018
  /// This function returns the source of the given path.
1003 1019
  template <typename Digraph, typename Path>
1004 1020
  typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
1005 1021
    return digraph.source(path.front());
1006 1022
  }
1007 1023

	
1008 1024
  /// \brief The target of a path
1009 1025
  ///
1010 1026
  /// This function returns the target of the given path.
1011 1027
  template <typename Digraph, typename Path>
1012 1028
  typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1013 1029
    return digraph.target(path.back());
1014 1030
  }
1015 1031

	
1016 1032
  /// \brief Class which helps to iterate through the nodes of a path
1017 1033
  ///
1018 1034
  /// In a sense, the path can be treated as a list of arcs. The
1019 1035
  /// lemon path type stores only this list. As a consequence, it
1020 1036
  /// cannot enumerate the nodes in the path and the zero length paths
1021 1037
  /// cannot have a source node.
1022 1038
  ///
1023 1039
  /// This class implements the node iterator of a path structure. To
1024 1040
  /// provide this feature, the underlying digraph should be passed to
1025 1041
  /// the constructor of the iterator.
1026 1042
  template <typename Path>
1027 1043
  class PathNodeIt {
1028 1044
  private:
1029 1045
    const typename Path::Digraph *_digraph;
1030 1046
    typename Path::ArcIt _it;
1031 1047
    typename Path::Digraph::Node _nd;
1032 1048

	
1033 1049
  public:
1034 1050

	
1035 1051
    typedef typename Path::Digraph Digraph;
1036 1052
    typedef typename Digraph::Node Node;
1037 1053

	
1038 1054
    /// Default constructor
1039 1055
    PathNodeIt() {}
1040 1056
    /// Invalid constructor
1041 1057
    PathNodeIt(Invalid)
1042 1058
      : _digraph(0), _it(INVALID), _nd(INVALID) {}
1043 1059
    /// Constructor
1044 1060
    PathNodeIt(const Digraph& digraph, const Path& path)
1045 1061
      : _digraph(&digraph), _it(path) {
1046 1062
      _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1047 1063
    }
1048 1064
    /// Constructor
1049 1065
    PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
1050 1066
      : _digraph(&digraph), _it(path), _nd(src) {}
1051 1067

	
1052 1068
    ///Conversion to Digraph::Node
1053 1069
    operator Node() const {
1054 1070
      return _nd;
1055 1071
    }
1056 1072

	
1057 1073
    /// Next node
1058 1074
    PathNodeIt& operator++() {
1059 1075
      if (_it == INVALID) _nd = INVALID;
1060 1076
      else {
1061 1077
        _nd = _digraph->target(_it);
1062 1078
        ++_it;
1063 1079
      }
1064 1080
      return *this;
1065 1081
    }
1066 1082

	
1067 1083
    /// Comparison operator
1068 1084
    bool operator==(const PathNodeIt& n) const {
1069 1085
      return _it == n._it && _nd == n._nd;
1070 1086
    }
1071 1087
    /// Comparison operator
1072 1088
    bool operator!=(const PathNodeIt& n) const {
1073 1089
      return _it != n._it || _nd != n._nd;
1074 1090
    }
1075 1091
    /// Comparison operator
1076 1092
    bool operator<(const PathNodeIt& n) const {
1077 1093
      return (_it < n._it && _nd != INVALID);
1078 1094
    }
1079 1095

	
1080 1096
  };
1081 1097

	
1082 1098
  ///@}
1083 1099

	
1084 1100
} // namespace lemon
1085 1101

	
1086 1102
#endif // LEMON_PATH_H
Ignore white space 1536 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
/*
20 20
 * This file contains the reimplemented version of the Mersenne Twister
21 21
 * Generator of Matsumoto and Nishimura.
22 22
 *
23 23
 * See the appropriate copyright notice below.
24 24
 *
25 25
 * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
26 26
 * All rights reserved.
27 27
 *
28 28
 * Redistribution and use in source and binary forms, with or without
29 29
 * modification, are permitted provided that the following conditions
30 30
 * are met:
31 31
 *
32 32
 * 1. Redistributions of source code must retain the above copyright
33 33
 *    notice, this list of conditions and the following disclaimer.
34 34
 *
35 35
 * 2. Redistributions in binary form must reproduce the above copyright
36 36
 *    notice, this list of conditions and the following disclaimer in the
37 37
 *    documentation and/or other materials provided with the distribution.
38 38
 *
39 39
 * 3. The names of its contributors may not be used to endorse or promote
40 40
 *    products derived from this software without specific prior written
41 41
 *    permission.
42 42
 *
43 43
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 44
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 45
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
46 46
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
47 47
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
48 48
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49 49
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
50 50
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 51
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
52 52
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53 53
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
54 54
 * OF THE POSSIBILITY OF SUCH DAMAGE.
55 55
 *
56 56
 *
57 57
 * Any feedback is very welcome.
58 58
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
59 59
 * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
60 60
 */
61 61

	
62 62
#ifndef LEMON_RANDOM_H
63 63
#define LEMON_RANDOM_H
64 64

	
65 65
#include <algorithm>
66 66
#include <iterator>
67 67
#include <vector>
68 68
#include <limits>
69 69
#include <fstream>
70 70

	
71 71
#include <lemon/math.h>
72 72
#include <lemon/dim2.h>
73 73

	
74 74
#ifndef WIN32
75 75
#include <sys/time.h>
76 76
#include <ctime>
77 77
#include <sys/types.h>
78 78
#include <unistd.h>
79 79
#else
80 80
#include <lemon/bits/windows.h>
81 81
#endif
82 82

	
83 83
///\ingroup misc
84 84
///\file
85 85
///\brief Mersenne Twister random number generator
86 86

	
87 87
namespace lemon {
88 88

	
89 89
  namespace _random_bits {
90 90

	
91 91
    template <typename _Word, int _bits = std::numeric_limits<_Word>::digits>
92 92
    struct RandomTraits {};
93 93

	
94 94
    template <typename _Word>
95 95
    struct RandomTraits<_Word, 32> {
96 96

	
97 97
      typedef _Word Word;
98 98
      static const int bits = 32;
99 99

	
100 100
      static const int length = 624;
101 101
      static const int shift = 397;
102 102

	
103 103
      static const Word mul = 0x6c078965u;
104 104
      static const Word arrayInit = 0x012BD6AAu;
105 105
      static const Word arrayMul1 = 0x0019660Du;
106 106
      static const Word arrayMul2 = 0x5D588B65u;
107 107

	
108 108
      static const Word mask = 0x9908B0DFu;
109 109
      static const Word loMask = (1u << 31) - 1;
110 110
      static const Word hiMask = ~loMask;
111 111

	
112 112

	
113 113
      static Word tempering(Word rnd) {
114 114
        rnd ^= (rnd >> 11);
115 115
        rnd ^= (rnd << 7) & 0x9D2C5680u;
116 116
        rnd ^= (rnd << 15) & 0xEFC60000u;
117 117
        rnd ^= (rnd >> 18);
118 118
        return rnd;
119 119
      }
120 120

	
121 121
    };
122 122

	
123 123
    template <typename _Word>
124 124
    struct RandomTraits<_Word, 64> {
125 125

	
126 126
      typedef _Word Word;
127 127
      static const int bits = 64;
128 128

	
129 129
      static const int length = 312;
130 130
      static const int shift = 156;
131 131

	
132 132
      static const Word mul = Word(0x5851F42Du) << 32 | Word(0x4C957F2Du);
133 133
      static const Word arrayInit = Word(0x00000000u) << 32 |Word(0x012BD6AAu);
134 134
      static const Word arrayMul1 = Word(0x369DEA0Fu) << 32 |Word(0x31A53F85u);
135 135
      static const Word arrayMul2 = Word(0x27BB2EE6u) << 32 |Word(0x87B0B0FDu);
136 136

	
137 137
      static const Word mask = Word(0xB5026F5Au) << 32 | Word(0xA96619E9u);
138 138
      static const Word loMask = (Word(1u) << 31) - 1;
139 139
      static const Word hiMask = ~loMask;
140 140

	
141 141
      static Word tempering(Word rnd) {
142 142
        rnd ^= (rnd >> 29) & (Word(0x55555555u) << 32 | Word(0x55555555u));
143 143
        rnd ^= (rnd << 17) & (Word(0x71D67FFFu) << 32 | Word(0xEDA60000u));
144 144
        rnd ^= (rnd << 37) & (Word(0xFFF7EEE0u) << 32 | Word(0x00000000u));
145 145
        rnd ^= (rnd >> 43);
146 146
        return rnd;
147 147
      }
148 148

	
149 149
    };
150 150

	
151 151
    template <typename _Word>
152 152
    class RandomCore {
153 153
    public:
154 154

	
155 155
      typedef _Word Word;
156 156

	
157 157
    private:
158 158

	
159 159
      static const int bits = RandomTraits<Word>::bits;
160 160

	
161 161
      static const int length = RandomTraits<Word>::length;
162 162
      static const int shift = RandomTraits<Word>::shift;
163 163

	
164 164
    public:
165 165

	
166 166
      void initState() {
167 167
        static const Word seedArray[4] = {
168 168
          0x12345u, 0x23456u, 0x34567u, 0x45678u
169 169
        };
170 170

	
171 171
        initState(seedArray, seedArray + 4);
172 172
      }
173 173

	
174 174
      void initState(Word seed) {
175 175

	
176 176
        static const Word mul = RandomTraits<Word>::mul;
177 177

	
178 178
        current = state;
179 179

	
180 180
        Word *curr = state + length - 1;
181 181
        curr[0] = seed; --curr;
182 182
        for (int i = 1; i < length; ++i) {
183 183
          curr[0] = (mul * ( curr[1] ^ (curr[1] >> (bits - 2)) ) + i);
184 184
          --curr;
185 185
        }
186 186
      }
187 187

	
188 188
      template <typename Iterator>
189 189
      void initState(Iterator begin, Iterator end) {
190 190

	
191 191
        static const Word init = RandomTraits<Word>::arrayInit;
192 192
        static const Word mul1 = RandomTraits<Word>::arrayMul1;
193 193
        static const Word mul2 = RandomTraits<Word>::arrayMul2;
194 194

	
195 195

	
196 196
        Word *curr = state + length - 1; --curr;
197 197
        Iterator it = begin; int cnt = 0;
198 198
        int num;
199 199

	
200 200
        initState(init);
201 201

	
202 202
        num = length > end - begin ? length : end - begin;
203 203
        while (num--) {
204 204
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1))
205 205
            + *it + cnt;
206 206
          ++it; ++cnt;
207 207
          if (it == end) {
208 208
            it = begin; cnt = 0;
209 209
          }
210 210
          if (curr == state) {
211 211
            curr = state + length - 1; curr[0] = state[0];
212 212
          }
213 213
          --curr;
214 214
        }
215 215

	
216 216
        num = length - 1; cnt = length - (curr - state) - 1;
217 217
        while (num--) {
218 218
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2))
219 219
            - cnt;
220 220
          --curr; ++cnt;
221 221
          if (curr == state) {
222 222
            curr = state + length - 1; curr[0] = state[0]; --curr;
223 223
            cnt = 1;
224 224
          }
225 225
        }
226 226

	
227 227
        state[length - 1] = Word(1) << (bits - 1);
228 228
      }
229 229

	
230 230
      void copyState(const RandomCore& other) {
231 231
        std::copy(other.state, other.state + length, state);
232 232
        current = state + (other.current - other.state);
233 233
      }
234 234

	
235 235
      Word operator()() {
236 236
        if (current == state) fillState();
237 237
        --current;
238 238
        Word rnd = *current;
239 239
        return RandomTraits<Word>::tempering(rnd);
240 240
      }
241 241

	
242 242
    private:
243 243

	
244 244

	
245 245
      void fillState() {
246 246
        static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
247 247
        static const Word loMask = RandomTraits<Word>::loMask;
248 248
        static const Word hiMask = RandomTraits<Word>::hiMask;
249 249

	
250 250
        current = state + length;
251 251

	
252 252
        register Word *curr = state + length - 1;
253 253
        register long num;
254 254

	
255 255
        num = length - shift;
256 256
        while (num--) {
257 257
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
258 258
            curr[- shift] ^ mask[curr[-1] & 1ul];
259 259
          --curr;
260 260
        }
261 261
        num = shift - 1;
262 262
        while (num--) {
263 263
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
264 264
            curr[length - shift] ^ mask[curr[-1] & 1ul];
265 265
          --curr;
266 266
        }
267 267
        state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
268 268
          curr[length - shift] ^ mask[curr[length - 1] & 1ul];
269 269

	
270 270
      }
271 271

	
272 272

	
273 273
      Word *current;
274 274
      Word state[length];
275 275

	
276 276
    };
277 277

	
278 278

	
279 279
    template <typename Result,
280 280
              int shift = (std::numeric_limits<Result>::digits + 1) / 2>
281 281
    struct Masker {
282 282
      static Result mask(const Result& result) {
283 283
        return Masker<Result, (shift + 1) / 2>::
284 284
          mask(static_cast<Result>(result | (result >> shift)));
285 285
      }
286 286
    };
287 287

	
288 288
    template <typename Result>
289 289
    struct Masker<Result, 1> {
290 290
      static Result mask(const Result& result) {
291 291
        return static_cast<Result>(result | (result >> 1));
292 292
      }
293 293
    };
294 294

	
295 295
    template <typename Result, typename Word,
296 296
              int rest = std::numeric_limits<Result>::digits, int shift = 0,
297 297
              bool last = rest <= std::numeric_limits<Word>::digits>
298 298
    struct IntConversion {
299 299
      static const int bits = std::numeric_limits<Word>::digits;
300 300

	
301 301
      static Result convert(RandomCore<Word>& rnd) {
302 302
        return static_cast<Result>(rnd() >> (bits - rest)) << shift;
303 303
      }
304 304

	
305 305
    };
306 306

	
307 307
    template <typename Result, typename Word, int rest, int shift>
308 308
    struct IntConversion<Result, Word, rest, shift, false> {
309 309
      static const int bits = std::numeric_limits<Word>::digits;
310 310

	
311 311
      static Result convert(RandomCore<Word>& rnd) {
312 312
        return (static_cast<Result>(rnd()) << shift) |
313 313
          IntConversion<Result, Word, rest - bits, shift + bits>::convert(rnd);
314 314
      }
315 315
    };
316 316

	
317 317

	
318 318
    template <typename Result, typename Word,
319 319
              bool one_word = (std::numeric_limits<Word>::digits <
320 320
                               std::numeric_limits<Result>::digits) >
321 321
    struct Mapping {
322 322
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
323 323
        Word max = Word(bound - 1);
324 324
        Result mask = Masker<Result>::mask(bound - 1);
325 325
        Result num;
326 326
        do {
327 327
          num = IntConversion<Result, Word>::convert(rnd) & mask;
328 328
        } while (num > max);
329 329
        return num;
330 330
      }
331 331
    };
332 332

	
333 333
    template <typename Result, typename Word>
334 334
    struct Mapping<Result, Word, false> {
335 335
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
336 336
        Word max = Word(bound - 1);
337 337
        Word mask = Masker<Word, (std::numeric_limits<Result>::digits + 1) / 2>
338 338
          ::mask(max);
339 339
        Word num;
340 340
        do {
341 341
          num = rnd() & mask;
342 342
        } while (num > max);
343 343
        return num;
344 344
      }
345 345
    };
346 346

	
347
    template <typename Result, int exp, bool pos = (exp >= 0)>
347
    template <typename Result, int exp>
348 348
    struct ShiftMultiplier {
349 349
      static const Result multiplier() {
350 350
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
351 351
        res *= res;
352
        if ((exp & 1) == 1) res *= static_cast<Result>(2.0);
353
        return res;
354
      }
355
    };
356

	
357
    template <typename Result, int exp>
358
    struct ShiftMultiplier<Result, exp, false> {
359
      static const Result multiplier() {
360
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
361
        res *= res;
362 352
        if ((exp & 1) == 1) res *= static_cast<Result>(0.5);
363 353
        return res;
364 354
      }
365 355
    };
366 356

	
367 357
    template <typename Result>
368
    struct ShiftMultiplier<Result, 0, true> {
358
    struct ShiftMultiplier<Result, 0> {
369 359
      static const Result multiplier() {
370 360
        return static_cast<Result>(1.0);
371 361
      }
372 362
    };
373 363

	
374 364
    template <typename Result>
375
    struct ShiftMultiplier<Result, -20, true> {
365
    struct ShiftMultiplier<Result, 20> {
376 366
      static const Result multiplier() {
377 367
        return static_cast<Result>(1.0/1048576.0);
378 368
      }
379 369
    };
380 370

	
381 371
    template <typename Result>
382
    struct ShiftMultiplier<Result, -32, true> {
372
    struct ShiftMultiplier<Result, 32> {
383 373
      static const Result multiplier() {
384
        return static_cast<Result>(1.0/424967296.0);
374
        return static_cast<Result>(1.0/4294967296.0);
385 375
      }
386 376
    };
387 377

	
388 378
    template <typename Result>
389
    struct ShiftMultiplier<Result, -53, true> {
379
    struct ShiftMultiplier<Result, 53> {
390 380
      static const Result multiplier() {
391 381
        return static_cast<Result>(1.0/9007199254740992.0);
392 382
      }
393 383
    };
394 384

	
395 385
    template <typename Result>
396
    struct ShiftMultiplier<Result, -64, true> {
386
    struct ShiftMultiplier<Result, 64> {
397 387
      static const Result multiplier() {
398 388
        return static_cast<Result>(1.0/18446744073709551616.0);
399 389
      }
400 390
    };
401 391

	
402 392
    template <typename Result, int exp>
403 393
    struct Shifting {
404 394
      static Result shift(const Result& result) {
405 395
        return result * ShiftMultiplier<Result, exp>::multiplier();
406 396
      }
407 397
    };
408 398

	
409 399
    template <typename Result, typename Word,
410 400
              int rest = std::numeric_limits<Result>::digits, int shift = 0,
411 401
              bool last = rest <= std::numeric_limits<Word>::digits>
412 402
    struct RealConversion{
413 403
      static const int bits = std::numeric_limits<Word>::digits;
414 404

	
415 405
      static Result convert(RandomCore<Word>& rnd) {
416
        return Shifting<Result, - shift - rest>::
406
        return Shifting<Result, shift + rest>::
417 407
          shift(static_cast<Result>(rnd() >> (bits - rest)));
418 408
      }
419 409
    };
420 410

	
421 411
    template <typename Result, typename Word, int rest, int shift>
422 412
    struct RealConversion<Result, Word, rest, shift, false> {
423 413
      static const int bits = std::numeric_limits<Word>::digits;
424 414

	
425 415
      static Result convert(RandomCore<Word>& rnd) {
426
        return Shifting<Result, - shift - bits>::
416
        return Shifting<Result, shift + bits>::
427 417
          shift(static_cast<Result>(rnd())) +
428 418
          RealConversion<Result, Word, rest-bits, shift + bits>::
429 419
          convert(rnd);
430 420
      }
431 421
    };
432 422

	
433 423
    template <typename Result, typename Word>
434 424
    struct Initializer {
435 425

	
436 426
      template <typename Iterator>
437 427
      static void init(RandomCore<Word>& rnd, Iterator begin, Iterator end) {
438 428
        std::vector<Word> ws;
439 429
        for (Iterator it = begin; it != end; ++it) {
440 430
          ws.push_back(Word(*it));
441 431
        }
442 432
        rnd.initState(ws.begin(), ws.end());
443 433
      }
444 434

	
445 435
      static void init(RandomCore<Word>& rnd, Result seed) {
446 436
        rnd.initState(seed);
447 437
      }
448 438
    };
449 439

	
450 440
    template <typename Word>
451 441
    struct BoolConversion {
452 442
      static bool convert(RandomCore<Word>& rnd) {
453 443
        return (rnd() & 1) == 1;
454 444
      }
455 445
    };
456 446

	
457 447
    template <typename Word>
458 448
    struct BoolProducer {
459 449
      Word buffer;
460 450
      int num;
461 451

	
462 452
      BoolProducer() : num(0) {}
463 453

	
464 454
      bool convert(RandomCore<Word>& rnd) {
465 455
        if (num == 0) {
466 456
          buffer = rnd();
467 457
          num = RandomTraits<Word>::bits;
468 458
        }
469 459
        bool r = (buffer & 1);
470 460
        buffer >>= 1;
471 461
        --num;
472 462
        return r;
473 463
      }
474 464
    };
475 465

	
476 466
  }
477 467

	
478 468
  /// \ingroup misc
479 469
  ///
480 470
  /// \brief Mersenne Twister random number generator
481 471
  ///
482 472
  /// The Mersenne Twister is a twisted generalized feedback
483 473
  /// shift-register generator of Matsumoto and Nishimura. The period
484 474
  /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
485 475
  /// equi-distributed in 623 dimensions for 32-bit numbers. The time
486 476
  /// performance of this generator is comparable to the commonly used
487 477
  /// generators.
488 478
  ///
489 479
  /// This implementation is specialized for both 32-bit and 64-bit
490 480
  /// architectures. The generators differ sligthly in the
491 481
  /// initialization and generation phase so they produce two
492 482
  /// completly different sequences.
493 483
  ///
494 484
  /// The generator gives back random numbers of serveral types. To
495 485
  /// get a random number from a range of a floating point type you
496 486
  /// can use one form of the \c operator() or the \c real() member
497 487
  /// function. If you want to get random number from the {0, 1, ...,
498 488
  /// n-1} integer range use the \c operator[] or the \c integer()
499 489
  /// method. And to get random number from the whole range of an
500 490
  /// integer type you can use the argumentless \c integer() or \c
501 491
  /// uinteger() functions. After all you can get random bool with
502 492
  /// equal chance of true and false or given probability of true
503 493
  /// result with the \c boolean() member functions.
504 494
  ///
505 495
  ///\code
506 496
  /// // The commented code is identical to the other
507 497
  /// double a = rnd();                     // [0.0, 1.0)
508 498
  /// // double a = rnd.real();             // [0.0, 1.0)
509 499
  /// double b = rnd(100.0);                // [0.0, 100.0)
510 500
  /// // double b = rnd.real(100.0);        // [0.0, 100.0)
511 501
  /// double c = rnd(1.0, 2.0);             // [1.0, 2.0)
512 502
  /// // double c = rnd.real(1.0, 2.0);     // [1.0, 2.0)
513 503
  /// int d = rnd[100000];                  // 0..99999
514 504
  /// // int d = rnd.integer(100000);       // 0..99999
515 505
  /// int e = rnd[6] + 1;                   // 1..6
516 506
  /// // int e = rnd.integer(1, 1 + 6);     // 1..6
517 507
  /// int b = rnd.uinteger<int>();          // 0 .. 2^31 - 1
518 508
  /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
519 509
  /// bool g = rnd.boolean();               // P(g = true) = 0.5
520 510
  /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
521 511
  ///\endcode
522 512
  ///
523 513
  /// LEMON provides a global instance of the random number
524 514
  /// generator which name is \ref lemon::rnd "rnd". Usually it is a
525 515
  /// good programming convenience to use this global generator to get
526 516
  /// random numbers.
527 517
  class Random {
528 518
  private:
529 519

	
530 520
    // Architecture word
531 521
    typedef unsigned long Word;
532 522

	
533 523
    _random_bits::RandomCore<Word> core;
534 524
    _random_bits::BoolProducer<Word> bool_producer;
535 525

	
536 526

	
537 527
  public:
538 528

	
539 529
    ///\name Initialization
540 530
    ///
541 531
    /// @{
542 532

	
543 533
    ///\name Initialization
544 534
    ///
545 535
    /// @{
546 536

	
547 537
    /// \brief Default constructor
548 538
    ///
549 539
    /// Constructor with constant seeding.
550 540
    Random() { core.initState(); }
551 541

	
552 542
    /// \brief Constructor with seed
553 543
    ///
554 544
    /// Constructor with seed. The current number type will be converted
555 545
    /// to the architecture word type.
556 546
    template <typename Number>
557 547
    Random(Number seed) {
558 548
      _random_bits::Initializer<Number, Word>::init(core, seed);
559 549
    }
560 550

	
561 551
    /// \brief Constructor with array seeding
562 552
    ///
563 553
    /// Constructor with array seeding. The given range should contain
564 554
    /// any number type and the numbers will be converted to the
565 555
    /// architecture word type.
566 556
    template <typename Iterator>
567 557
    Random(Iterator begin, Iterator end) {
568 558
      typedef typename std::iterator_traits<Iterator>::value_type Number;
569 559
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
570 560
    }
571 561

	
572 562
    /// \brief Copy constructor
573 563
    ///
574 564
    /// Copy constructor. The generated sequence will be identical to
575 565
    /// the other sequence. It can be used to save the current state
576 566
    /// of the generator and later use it to generate the same
577 567
    /// sequence.
578 568
    Random(const Random& other) {
579 569
      core.copyState(other.core);
580 570
    }
581 571

	
582 572
    /// \brief Assign operator
583 573
    ///
584 574
    /// Assign operator. The generated sequence will be identical to
585 575
    /// the other sequence. It can be used to save the current state
586 576
    /// of the generator and later use it to generate the same
587 577
    /// sequence.
588 578
    Random& operator=(const Random& other) {
589 579
      if (&other != this) {
590 580
        core.copyState(other.core);
591 581
      }
592 582
      return *this;
593 583
    }
594 584

	
595 585
    /// \brief Seeding random sequence
596 586
    ///
597 587
    /// Seeding the random sequence. The current number type will be
598 588
    /// converted to the architecture word type.
599 589
    template <typename Number>
600 590
    void seed(Number seed) {
601 591
      _random_bits::Initializer<Number, Word>::init(core, seed);
602 592
    }
603 593

	
604 594
    /// \brief Seeding random sequence
605 595
    ///
606 596
    /// Seeding the random sequence. The given range should contain
607 597
    /// any number type and the numbers will be converted to the
608 598
    /// architecture word type.
609 599
    template <typename Iterator>
610 600
    void seed(Iterator begin, Iterator end) {
611 601
      typedef typename std::iterator_traits<Iterator>::value_type Number;
612 602
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
613 603
    }
614 604

	
615 605
    /// \brief Seeding from file or from process id and time
616 606
    ///
617 607
    /// By default, this function calls the \c seedFromFile() member
618 608
    /// function with the <tt>/dev/urandom</tt> file. If it does not success,
619 609
    /// it uses the \c seedFromTime().
620 610
    /// \return Currently always true.
621 611
    bool seed() {
622 612
#ifndef WIN32
623 613
      if (seedFromFile("/dev/urandom", 0)) return true;
624 614
#endif
625 615
      if (seedFromTime()) return true;
626 616
      return false;
627 617
    }
628 618

	
629 619
    /// \brief Seeding from file
630 620
    ///
631 621
    /// Seeding the random sequence from file. The linux kernel has two
632 622
    /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
633 623
    /// could give good seed values for pseudo random generators (The
634 624
    /// difference between two devices is that the <tt>random</tt> may
635 625
    /// block the reading operation while the kernel can give good
636 626
    /// source of randomness, while the <tt>urandom</tt> does not
637 627
    /// block the input, but it could give back bytes with worse
638 628
    /// entropy).
639 629
    /// \param file The source file
640 630
    /// \param offset The offset, from the file read.
641 631
    /// \return True when the seeding successes.
642 632
#ifndef WIN32
643 633
    bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
644 634
#else
645 635
    bool seedFromFile(const std::string& file = "", int offset = 0)
646 636
#endif
647 637
    {
648 638
      std::ifstream rs(file.c_str());
649 639
      const int size = 4;
650 640
      Word buf[size];
651 641
      if (offset != 0 && !rs.seekg(offset)) return false;
652 642
      if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
653 643
      seed(buf, buf + size);
654 644
      return true;
655 645
    }
656 646

	
657 647
    /// \brief Seding from process id and time
658 648
    ///
659 649
    /// Seding from process id and time. This function uses the
660 650
    /// current process id and the current time for initialize the
661 651
    /// random sequence.
662 652
    /// \return Currently always true.
663 653
    bool seedFromTime() {
664 654
#ifndef WIN32
665 655
      timeval tv;
666 656
      gettimeofday(&tv, 0);
667 657
      seed(getpid() + tv.tv_sec + tv.tv_usec);
668 658
#else
669 659
      seed(bits::getWinRndSeed());
670 660
#endif
671 661
      return true;
672 662
    }
673 663

	
674 664
    /// @}
675 665

	
676 666
    ///\name Uniform distributions
677 667
    ///
678 668
    /// @{
679 669

	
680 670
    /// \brief Returns a random real number from the range [0, 1)
681 671
    ///
682 672
    /// It returns a random real number from the range [0, 1). The
683 673
    /// default Number type is \c double.
684 674
    template <typename Number>
685 675
    Number real() {
686 676
      return _random_bits::RealConversion<Number, Word>::convert(core);
687 677
    }
688 678

	
689 679
    double real() {
690 680
      return real<double>();
691 681
    }
692 682

	
693 683
    /// @}
694 684

	
695 685
    ///\name Uniform distributions
696 686
    ///
697 687
    /// @{
698 688

	
699 689
    /// \brief Returns a random real number from the range [0, 1)
700 690
    ///
701 691
    /// It returns a random double from the range [0, 1).
702 692
    double operator()() {
703 693
      return real<double>();
704 694
    }
705 695

	
706 696
    /// \brief Returns a random real number from the range [0, b)
707 697
    ///
708 698
    /// It returns a random real number from the range [0, b).
709 699
    double operator()(double b) {
710 700
      return real<double>() * b;
711 701
    }
712 702

	
713 703
    /// \brief Returns a random real number from the range [a, b)
714 704
    ///
715 705
    /// It returns a random real number from the range [a, b).
716 706
    double operator()(double a, double b) {
717 707
      return real<double>() * (b - a) + a;
718 708
    }
719 709

	
720 710
    /// \brief Returns a random integer from a range
721 711
    ///
722 712
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
723 713
    template <typename Number>
724 714
    Number integer(Number b) {
725 715
      return _random_bits::Mapping<Number, Word>::map(core, b);
726 716
    }
727 717

	
728 718
    /// \brief Returns a random integer from a range
729 719
    ///
730 720
    /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
731 721
    template <typename Number>
732 722
    Number integer(Number a, Number b) {
733 723
      return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
734 724
    }
735 725

	
736 726
    /// \brief Returns a random integer from a range
737 727
    ///
738 728
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
739 729
    template <typename Number>
740 730
    Number operator[](Number b) {
741 731
      return _random_bits::Mapping<Number, Word>::map(core, b);
742 732
    }
743 733

	
744 734
    /// \brief Returns a random non-negative integer
745 735
    ///
746 736
    /// It returns a random non-negative integer uniformly from the
747 737
    /// whole range of the current \c Number type. The default result
748 738
    /// type of this function is <tt>unsigned int</tt>.
749 739
    template <typename Number>
750 740
    Number uinteger() {
751 741
      return _random_bits::IntConversion<Number, Word>::convert(core);
752 742
    }
753 743

	
754 744
    /// @}
755 745

	
756 746
    unsigned int uinteger() {
757 747
      return uinteger<unsigned int>();
758 748
    }
759 749

	
760 750
    /// \brief Returns a random integer
761 751
    ///
762 752
    /// It returns a random integer uniformly from the whole range of
763 753
    /// the current \c Number type. The default result type of this
764 754
    /// function is \c int.
765 755
    template <typename Number>
766 756
    Number integer() {
767 757
      static const int nb = std::numeric_limits<Number>::digits +
768 758
        (std::numeric_limits<Number>::is_signed ? 1 : 0);
769 759
      return _random_bits::IntConversion<Number, Word, nb>::convert(core);
770 760
    }
771 761

	
772 762
    int integer() {
773 763
      return integer<int>();
774 764
    }
775 765

	
776 766
    /// \brief Returns a random bool
777 767
    ///
778 768
    /// It returns a random bool. The generator holds a buffer for
779 769
    /// random bits. Every time when it become empty the generator makes
780 770
    /// a new random word and fill the buffer up.
781 771
    bool boolean() {
782 772
      return bool_producer.convert(core);
783 773
    }
784 774

	
785 775
    /// @}
786 776

	
787 777
    ///\name Non-uniform distributions
788 778
    ///
789 779

	
790 780
    ///@{
791 781

	
792 782
    /// \brief Returns a random bool
793 783
    ///
794 784
    /// It returns a random bool with given probability of true result.
795 785
    bool boolean(double p) {
796 786
      return operator()() < p;
797 787
    }
798 788

	
799 789
    /// Standard Gauss distribution
800 790

	
801 791
    /// Standard Gauss distribution.
802 792
    /// \note The Cartesian form of the Box-Muller
803 793
    /// transformation is used to generate a random normal distribution.
804 794
    double gauss()
805 795
    {
806 796
      double V1,V2,S;
807 797
      do {
808 798
        V1=2*real<double>()-1;
809 799
        V2=2*real<double>()-1;
810 800
        S=V1*V1+V2*V2;
811 801
      } while(S>=1);
812 802
      return std::sqrt(-2*std::log(S)/S)*V1;
813 803
    }
814 804
    /// Gauss distribution with given mean and standard deviation
815 805

	
816 806
    /// Gauss distribution with given mean and standard deviation.
817 807
    /// \sa gauss()
818 808
    double gauss(double mean,double std_dev)
819 809
    {
820 810
      return gauss()*std_dev+mean;
821 811
    }
822 812

	
823 813
    /// Exponential distribution with given mean
824 814

	
825 815
    /// This function generates an exponential distribution random number
826 816
    /// with mean <tt>1/lambda</tt>.
827 817
    ///
828 818
    double exponential(double lambda=1.0)
829 819
    {
830 820
      return -std::log(1.0-real<double>())/lambda;
831 821
    }
832 822

	
833 823
    /// Gamma distribution with given integer shape
834 824

	
835 825
    /// This function generates a gamma distribution random number.
836 826
    ///
837 827
    ///\param k shape parameter (<tt>k>0</tt> integer)
838 828
    double gamma(int k)
839 829
    {
840 830
      double s = 0;
841 831
      for(int i=0;i<k;i++) s-=std::log(1.0-real<double>());
842 832
      return s;
843 833
    }
844 834

	
845 835
    /// Gamma distribution with given shape and scale parameter
846 836

	
847 837
    /// This function generates a gamma distribution random number.
848 838
    ///
849 839
    ///\param k shape parameter (<tt>k>0</tt>)
850 840
    ///\param theta scale parameter
851 841
    ///
852 842
    double gamma(double k,double theta=1.0)
853 843
    {
854 844
      double xi,nu;
855 845
      const double delta = k-std::floor(k);
856 846
      const double v0=E/(E-delta);
857 847
      do {
858 848
        double V0=1.0-real<double>();
859 849
        double V1=1.0-real<double>();
860 850
        double V2=1.0-real<double>();
861 851
        if(V2<=v0)
862 852
          {
863 853
            xi=std::pow(V1,1.0/delta);
864 854
            nu=V0*std::pow(xi,delta-1.0);
865 855
          }
866 856
        else
867 857
          {
868 858
            xi=1.0-std::log(V1);
869 859
            nu=V0*std::exp(-xi);
870 860
          }
871 861
      } while(nu>std::pow(xi,delta-1.0)*std::exp(-xi));
872 862
      return theta*(xi+gamma(int(std::floor(k))));
873 863
    }
874 864

	
875 865
    /// Weibull distribution
876 866

	
877 867
    /// This function generates a Weibull distribution random number.
878 868
    ///
879 869
    ///\param k shape parameter (<tt>k>0</tt>)
880 870
    ///\param lambda scale parameter (<tt>lambda>0</tt>)
881 871
    ///
882 872
    double weibull(double k,double lambda)
883 873
    {
884 874
      return lambda*pow(-std::log(1.0-real<double>()),1.0/k);
885 875
    }
886 876

	
887 877
    /// Pareto distribution
888 878

	
889 879
    /// This function generates a Pareto distribution random number.
890 880
    ///
891 881
    ///\param k shape parameter (<tt>k>0</tt>)
892 882
    ///\param x_min location parameter (<tt>x_min>0</tt>)
893 883
    ///
894 884
    double pareto(double k,double x_min)
895 885
    {
896 886
      return exponential(gamma(k,1.0/x_min))+x_min;
897 887
    }
898 888

	
899 889
    /// Poisson distribution
900 890

	
901 891
    /// This function generates a Poisson distribution random number with
902 892
    /// parameter \c lambda.
903 893
    ///
904 894
    /// The probability mass function of this distribusion is
905 895
    /// \f[ \frac{e^{-\lambda}\lambda^k}{k!} \f]
906 896
    /// \note The algorithm is taken from the book of Donald E. Knuth titled
907 897
    /// ''Seminumerical Algorithms'' (1969). Its running time is linear in the
908 898
    /// return value.
909 899

	
910 900
    int poisson(double lambda)
911 901
    {
912 902
      const double l = std::exp(-lambda);
913 903
      int k=0;
914 904
      double p = 1.0;
915 905
      do {
916 906
        k++;
917 907
        p*=real<double>();
918 908
      } while (p>=l);
919 909
      return k-1;
920 910
    }
921 911

	
922 912
    ///@}
923 913

	
924 914
    ///\name Two dimensional distributions
925 915
    ///
926 916

	
927 917
    ///@{
928 918

	
929 919
    /// Uniform distribution on the full unit circle
930 920

	
931 921
    /// Uniform distribution on the full unit circle.
932 922
    ///
933 923
    dim2::Point<double> disc()
934 924
    {
935 925
      double V1,V2;
936 926
      do {
937 927
        V1=2*real<double>()-1;
938 928
        V2=2*real<double>()-1;
939 929

	
940 930
      } while(V1*V1+V2*V2>=1);
941 931
      return dim2::Point<double>(V1,V2);
942 932
    }
943 933
    /// A kind of two dimensional Gauss distribution
944 934

	
945 935
    /// This function provides a turning symmetric two-dimensional distribution.
946 936
    /// Both coordinates are of standard normal distribution, but they are not
947 937
    /// independent.
948 938
    ///
949 939
    /// \note The coordinates are the two random variables provided by
950 940
    /// the Box-Muller method.
951 941
    dim2::Point<double> gauss2()
952 942
    {
953 943
      double V1,V2,S;
954 944
      do {
955 945
        V1=2*real<double>()-1;
956 946
        V2=2*real<double>()-1;
957 947
        S=V1*V1+V2*V2;
958 948
      } while(S>=1);
959 949
      double W=std::sqrt(-2*std::log(S)/S);
960 950
      return dim2::Point<double>(W*V1,W*V2);
961 951
    }
962 952
    /// A kind of two dimensional exponential distribution
963 953

	
964 954
    /// This function provides a turning symmetric two-dimensional distribution.
965 955
    /// The x-coordinate is of conditionally exponential distribution
966 956
    /// with the condition that x is positive and y=0. If x is negative and
967 957
    /// y=0 then, -x is of exponential distribution. The same is true for the
968 958
    /// y-coordinate.
969 959
    dim2::Point<double> exponential2()
970 960
    {
971 961
      double V1,V2,S;
972 962
      do {
973 963
        V1=2*real<double>()-1;
974 964
        V2=2*real<double>()-1;
975 965
        S=V1*V1+V2*V2;
976 966
      } while(S>=1);
977 967
      double W=-std::log(S)/S;
978 968
      return dim2::Point<double>(W*V1,W*V2);
979 969
    }
980 970

	
981 971
    ///@}
982 972
  };
983 973

	
984 974

	
985 975
  extern Random rnd;
986 976

	
987 977
}
988 978

	
989 979
#endif
0 comments (0 inline)