gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
arrert.h is now included by core.h (#161)
0 4 0
default
4 files changed with 1 insertions and 3 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
#ifndef LEMON_CORE_H
20 20
#define LEMON_CORE_H
21 21

	
22 22
#include <vector>
23 23
#include <algorithm>
24 24

	
25 25
#include <lemon/bits/enable_if.h>
26 26
#include <lemon/bits/traits.h>
27
#include <lemon/assert.h>
27 28

	
28 29
///\file
29 30
///\brief LEMON core utilities.
30 31
///
31 32
///This header file contains core utilities for LEMON.
32 33
///It is automatically included by all graph types, therefore it usually
33 34
///do not have to be included directly.
34 35

	
35 36
namespace lemon {
36 37

	
37 38
  /// \brief Dummy type to make it easier to create invalid iterators.
38 39
  ///
39 40
  /// Dummy type to make it easier to create invalid iterators.
40 41
  /// See \ref INVALID for the usage.
41 42
  struct Invalid {
42 43
  public:
43 44
    bool operator==(Invalid) { return true;  }
44 45
    bool operator!=(Invalid) { return false; }
45 46
    bool operator< (Invalid) { return false; }
46 47
  };
47 48

	
48 49
  /// \brief Invalid iterators.
49 50
  ///
50 51
  /// \ref Invalid is a global type that converts to each iterator
51 52
  /// in such a way that the value of the target iterator will be invalid.
52 53
#ifdef LEMON_ONLY_TEMPLATES
53 54
  const Invalid INVALID = Invalid();
54 55
#else
55 56
  extern const Invalid INVALID;
56 57
#endif
57 58

	
58 59
  /// \addtogroup gutils
59 60
  /// @{
60 61

	
61 62
  ///Create convenience typedefs for the digraph types and iterators
62 63

	
63 64
  ///This \c \#define creates convenient type definitions for the following
64 65
  ///types of \c Digraph: \c Node,  \c NodeIt, \c Arc, \c ArcIt, \c InArcIt,
65 66
  ///\c OutArcIt, \c BoolNodeMap, \c IntNodeMap, \c DoubleNodeMap,
66 67
  ///\c BoolArcMap, \c IntArcMap, \c DoubleArcMap.
67 68
  ///
68 69
  ///\note If the graph type is a dependent type, ie. the graph type depend
69 70
  ///on a template parameter, then use \c TEMPLATE_DIGRAPH_TYPEDEFS()
70 71
  ///macro.
71 72
#define DIGRAPH_TYPEDEFS(Digraph)                                       \
72 73
  typedef Digraph::Node Node;                                           \
73 74
  typedef Digraph::NodeIt NodeIt;                                       \
74 75
  typedef Digraph::Arc Arc;                                             \
75 76
  typedef Digraph::ArcIt ArcIt;                                         \
76 77
  typedef Digraph::InArcIt InArcIt;                                     \
77 78
  typedef Digraph::OutArcIt OutArcIt;                                   \
78 79
  typedef Digraph::NodeMap<bool> BoolNodeMap;                           \
79 80
  typedef Digraph::NodeMap<int> IntNodeMap;                             \
80 81
  typedef Digraph::NodeMap<double> DoubleNodeMap;                       \
81 82
  typedef Digraph::ArcMap<bool> BoolArcMap;                             \
82 83
  typedef Digraph::ArcMap<int> IntArcMap;                               \
83 84
  typedef Digraph::ArcMap<double> DoubleArcMap
84 85

	
85 86
  ///Create convenience typedefs for the digraph types and iterators
86 87

	
87 88
  ///\see DIGRAPH_TYPEDEFS
88 89
  ///
89 90
  ///\note Use this macro, if the graph type is a dependent type,
90 91
  ///ie. the graph type depend on a template parameter.
91 92
#define TEMPLATE_DIGRAPH_TYPEDEFS(Digraph)                              \
92 93
  typedef typename Digraph::Node Node;                                  \
93 94
  typedef typename Digraph::NodeIt NodeIt;                              \
94 95
  typedef typename Digraph::Arc Arc;                                    \
95 96
  typedef typename Digraph::ArcIt ArcIt;                                \
96 97
  typedef typename Digraph::InArcIt InArcIt;                            \
97 98
  typedef typename Digraph::OutArcIt OutArcIt;                          \
98 99
  typedef typename Digraph::template NodeMap<bool> BoolNodeMap;         \
99 100
  typedef typename Digraph::template NodeMap<int> IntNodeMap;           \
100 101
  typedef typename Digraph::template NodeMap<double> DoubleNodeMap;     \
101 102
  typedef typename Digraph::template ArcMap<bool> BoolArcMap;           \
102 103
  typedef typename Digraph::template ArcMap<int> IntArcMap;             \
103 104
  typedef typename Digraph::template ArcMap<double> DoubleArcMap
104 105

	
105 106
  ///Create convenience typedefs for the graph types and iterators
106 107

	
107 108
  ///This \c \#define creates the same convenient type definitions as defined
108 109
  ///by \ref DIGRAPH_TYPEDEFS(Graph) and six more, namely it creates
109 110
  ///\c Edge, \c EdgeIt, \c IncEdgeIt, \c BoolEdgeMap, \c IntEdgeMap,
110 111
  ///\c DoubleEdgeMap.
111 112
  ///
112 113
  ///\note If the graph type is a dependent type, ie. the graph type depend
113 114
  ///on a template parameter, then use \c TEMPLATE_GRAPH_TYPEDEFS()
114 115
  ///macro.
115 116
#define GRAPH_TYPEDEFS(Graph)                                           \
116 117
  DIGRAPH_TYPEDEFS(Graph);                                              \
117 118
  typedef Graph::Edge Edge;                                             \
118 119
  typedef Graph::EdgeIt EdgeIt;                                         \
119 120
  typedef Graph::IncEdgeIt IncEdgeIt;                                   \
120 121
  typedef Graph::EdgeMap<bool> BoolEdgeMap;                             \
121 122
  typedef Graph::EdgeMap<int> IntEdgeMap;                               \
122 123
  typedef Graph::EdgeMap<double> DoubleEdgeMap
123 124

	
124 125
  ///Create convenience typedefs for the graph types and iterators
125 126

	
126 127
  ///\see GRAPH_TYPEDEFS
127 128
  ///
128 129
  ///\note Use this macro, if the graph type is a dependent type,
129 130
  ///ie. the graph type depend on a template parameter.
130 131
#define TEMPLATE_GRAPH_TYPEDEFS(Graph)                                  \
131 132
  TEMPLATE_DIGRAPH_TYPEDEFS(Graph);                                     \
132 133
  typedef typename Graph::Edge Edge;                                    \
133 134
  typedef typename Graph::EdgeIt EdgeIt;                                \
134 135
  typedef typename Graph::IncEdgeIt IncEdgeIt;                          \
135 136
  typedef typename Graph::template EdgeMap<bool> BoolEdgeMap;           \
136 137
  typedef typename Graph::template EdgeMap<int> IntEdgeMap;             \
137 138
  typedef typename Graph::template EdgeMap<double> DoubleEdgeMap
138 139

	
139 140
  /// \brief Function to count the items in a graph.
140 141
  ///
141 142
  /// This function counts the items (nodes, arcs etc.) in a graph.
142 143
  /// The complexity of the function is linear because
143 144
  /// it iterates on all of the items.
144 145
  template <typename Graph, typename Item>
145 146
  inline int countItems(const Graph& g) {
146 147
    typedef typename ItemSetTraits<Graph, Item>::ItemIt ItemIt;
147 148
    int num = 0;
148 149
    for (ItemIt it(g); it != INVALID; ++it) {
149 150
      ++num;
150 151
    }
151 152
    return num;
152 153
  }
153 154

	
154 155
  // Node counting:
155 156

	
156 157
  namespace _core_bits {
157 158

	
158 159
    template <typename Graph, typename Enable = void>
159 160
    struct CountNodesSelector {
160 161
      static int count(const Graph &g) {
161 162
        return countItems<Graph, typename Graph::Node>(g);
162 163
      }
163 164
    };
164 165

	
165 166
    template <typename Graph>
166 167
    struct CountNodesSelector<
167 168
      Graph, typename
168 169
      enable_if<typename Graph::NodeNumTag, void>::type>
169 170
    {
170 171
      static int count(const Graph &g) {
171 172
        return g.nodeNum();
172 173
      }
173 174
    };
174 175
  }
175 176

	
176 177
  /// \brief Function to count the nodes in the graph.
177 178
  ///
178 179
  /// This function counts the nodes in the graph.
179 180
  /// The complexity of the function is <em>O</em>(<em>n</em>), but for some
180 181
  /// graph structures it is specialized to run in <em>O</em>(1).
181 182
  ///
182 183
  /// \note If the graph contains a \c nodeNum() member function and a
183 184
  /// \c NodeNumTag tag then this function calls directly the member
184 185
  /// function to query the cardinality of the node set.
185 186
  template <typename Graph>
186 187
  inline int countNodes(const Graph& g) {
187 188
    return _core_bits::CountNodesSelector<Graph>::count(g);
188 189
  }
189 190

	
190 191
  // Arc counting:
191 192

	
192 193
  namespace _core_bits {
193 194

	
194 195
    template <typename Graph, typename Enable = void>
195 196
    struct CountArcsSelector {
196 197
      static int count(const Graph &g) {
197 198
        return countItems<Graph, typename Graph::Arc>(g);
198 199
      }
199 200
    };
200 201

	
201 202
    template <typename Graph>
202 203
    struct CountArcsSelector<
203 204
      Graph,
204 205
      typename enable_if<typename Graph::ArcNumTag, void>::type>
205 206
    {
206 207
      static int count(const Graph &g) {
207 208
        return g.arcNum();
208 209
      }
209 210
    };
210 211
  }
211 212

	
212 213
  /// \brief Function to count the arcs in the graph.
213 214
  ///
214 215
  /// This function counts the arcs in the graph.
215 216
  /// The complexity of the function is <em>O</em>(<em>m</em>), but for some
216 217
  /// graph structures it is specialized to run in <em>O</em>(1).
217 218
  ///
218 219
  /// \note If the graph contains a \c arcNum() member function and a
219 220
  /// \c ArcNumTag tag then this function calls directly the member
220 221
  /// function to query the cardinality of the arc set.
221 222
  template <typename Graph>
222 223
  inline int countArcs(const Graph& g) {
223 224
    return _core_bits::CountArcsSelector<Graph>::count(g);
224 225
  }
225 226

	
226 227
  // Edge counting:
227 228

	
228 229
  namespace _core_bits {
229 230

	
230 231
    template <typename Graph, typename Enable = void>
231 232
    struct CountEdgesSelector {
232 233
      static int count(const Graph &g) {
233 234
        return countItems<Graph, typename Graph::Edge>(g);
234 235
      }
235 236
    };
236 237

	
237 238
    template <typename Graph>
238 239
    struct CountEdgesSelector<
239 240
      Graph,
240 241
      typename enable_if<typename Graph::EdgeNumTag, void>::type>
241 242
    {
242 243
      static int count(const Graph &g) {
243 244
        return g.edgeNum();
244 245
      }
245 246
    };
246 247
  }
247 248

	
248 249
  /// \brief Function to count the edges in the graph.
249 250
  ///
250 251
  /// This function counts the edges in the graph.
251 252
  /// The complexity of the function is <em>O</em>(<em>m</em>), but for some
252 253
  /// graph structures it is specialized to run in <em>O</em>(1).
253 254
  ///
254 255
  /// \note If the graph contains a \c edgeNum() member function and a
255 256
  /// \c EdgeNumTag tag then this function calls directly the member
256 257
  /// function to query the cardinality of the edge set.
257 258
  template <typename Graph>
258 259
  inline int countEdges(const Graph& g) {
259 260
    return _core_bits::CountEdgesSelector<Graph>::count(g);
260 261

	
261 262
  }
262 263

	
263 264

	
264 265
  template <typename Graph, typename DegIt>
265 266
  inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) {
266 267
    int num = 0;
267 268
    for (DegIt it(_g, _n); it != INVALID; ++it) {
268 269
      ++num;
269 270
    }
270 271
    return num;
271 272
  }
272 273

	
273 274
  /// \brief Function to count the number of the out-arcs from node \c n.
274 275
  ///
275 276
  /// This function counts the number of the out-arcs from node \c n
276 277
  /// in the graph \c g.
277 278
  template <typename Graph>
278 279
  inline int countOutArcs(const Graph& g,  const typename Graph::Node& n) {
279 280
    return countNodeDegree<Graph, typename Graph::OutArcIt>(g, n);
280 281
  }
281 282

	
282 283
  /// \brief Function to count the number of the in-arcs to node \c n.
283 284
  ///
284 285
  /// This function counts the number of the in-arcs to node \c n
285 286
  /// in the graph \c g.
286 287
  template <typename Graph>
287 288
  inline int countInArcs(const Graph& g,  const typename Graph::Node& n) {
288 289
    return countNodeDegree<Graph, typename Graph::InArcIt>(g, n);
289 290
  }
290 291

	
291 292
  /// \brief Function to count the number of the inc-edges to node \c n.
292 293
  ///
293 294
  /// This function counts the number of the inc-edges to node \c n
294 295
  /// in the undirected graph \c g.
295 296
  template <typename Graph>
296 297
  inline int countIncEdges(const Graph& g,  const typename Graph::Node& n) {
297 298
    return countNodeDegree<Graph, typename Graph::IncEdgeIt>(g, n);
298 299
  }
299 300

	
300 301
  namespace _core_bits {
301 302

	
302 303
    template <typename Digraph, typename Item, typename RefMap>
303 304
    class MapCopyBase {
304 305
    public:
305 306
      virtual void copy(const Digraph& from, const RefMap& refMap) = 0;
306 307

	
307 308
      virtual ~MapCopyBase() {}
308 309
    };
309 310

	
310 311
    template <typename Digraph, typename Item, typename RefMap,
311 312
              typename FromMap, typename ToMap>
312 313
    class MapCopy : public MapCopyBase<Digraph, Item, RefMap> {
313 314
    public:
314 315

	
315 316
      MapCopy(const FromMap& map, ToMap& tmap)
316 317
        : _map(map), _tmap(tmap) {}
317 318

	
318 319
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
319 320
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
320 321
        for (ItemIt it(digraph); it != INVALID; ++it) {
321 322
          _tmap.set(refMap[it], _map[it]);
322 323
        }
323 324
      }
324 325

	
325 326
    private:
326 327
      const FromMap& _map;
327 328
      ToMap& _tmap;
328 329
    };
329 330

	
330 331
    template <typename Digraph, typename Item, typename RefMap, typename It>
331 332
    class ItemCopy : public MapCopyBase<Digraph, Item, RefMap> {
332 333
    public:
333 334

	
334 335
      ItemCopy(const Item& item, It& it) : _item(item), _it(it) {}
335 336

	
336 337
      virtual void copy(const Digraph&, const RefMap& refMap) {
337 338
        _it = refMap[_item];
338 339
      }
339 340

	
340 341
    private:
341 342
      Item _item;
342 343
      It& _it;
343 344
    };
344 345

	
345 346
    template <typename Digraph, typename Item, typename RefMap, typename Ref>
346 347
    class RefCopy : public MapCopyBase<Digraph, Item, RefMap> {
347 348
    public:
348 349

	
349 350
      RefCopy(Ref& map) : _map(map) {}
350 351

	
351 352
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
352 353
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
353 354
        for (ItemIt it(digraph); it != INVALID; ++it) {
354 355
          _map.set(it, refMap[it]);
355 356
        }
356 357
      }
357 358

	
358 359
    private:
359 360
      Ref& _map;
360 361
    };
361 362

	
362 363
    template <typename Digraph, typename Item, typename RefMap,
363 364
              typename CrossRef>
364 365
    class CrossRefCopy : public MapCopyBase<Digraph, Item, RefMap> {
365 366
    public:
366 367

	
367 368
      CrossRefCopy(CrossRef& cmap) : _cmap(cmap) {}
368 369

	
369 370
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
370 371
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
371 372
        for (ItemIt it(digraph); it != INVALID; ++it) {
372 373
          _cmap.set(refMap[it], it);
373 374
        }
374 375
      }
375 376

	
376 377
    private:
377 378
      CrossRef& _cmap;
378 379
    };
379 380

	
380 381
    template <typename Digraph, typename Enable = void>
381 382
    struct DigraphCopySelector {
382 383
      template <typename From, typename NodeRefMap, typename ArcRefMap>
383 384
      static void copy(const From& from, Digraph &to,
384 385
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
385 386
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
386 387
          nodeRefMap[it] = to.addNode();
387 388
        }
388 389
        for (typename From::ArcIt it(from); it != INVALID; ++it) {
389 390
          arcRefMap[it] = to.addArc(nodeRefMap[from.source(it)],
390 391
                                    nodeRefMap[from.target(it)]);
391 392
        }
392 393
      }
393 394
    };
394 395

	
395 396
    template <typename Digraph>
396 397
    struct DigraphCopySelector<
397 398
      Digraph,
398 399
      typename enable_if<typename Digraph::BuildTag, void>::type>
399 400
    {
400 401
      template <typename From, typename NodeRefMap, typename ArcRefMap>
401 402
      static void copy(const From& from, Digraph &to,
402 403
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
403 404
        to.build(from, nodeRefMap, arcRefMap);
404 405
      }
405 406
    };
406 407

	
407 408
    template <typename Graph, typename Enable = void>
408 409
    struct GraphCopySelector {
409 410
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
410 411
      static void copy(const From& from, Graph &to,
411 412
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
412 413
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
413 414
          nodeRefMap[it] = to.addNode();
414 415
        }
415 416
        for (typename From::EdgeIt it(from); it != INVALID; ++it) {
416 417
          edgeRefMap[it] = to.addEdge(nodeRefMap[from.u(it)],
417 418
                                      nodeRefMap[from.v(it)]);
418 419
        }
419 420
      }
420 421
    };
421 422

	
422 423
    template <typename Graph>
423 424
    struct GraphCopySelector<
424 425
      Graph,
425 426
      typename enable_if<typename Graph::BuildTag, void>::type>
426 427
    {
427 428
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
428 429
      static void copy(const From& from, Graph &to,
429 430
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
430 431
        to.build(from, nodeRefMap, edgeRefMap);
431 432
      }
432 433
    };
433 434

	
434 435
  }
435 436

	
436 437
  /// \brief Class to copy a digraph.
437 438
  ///
438 439
  /// Class to copy a digraph to another digraph (duplicate a digraph). The
439 440
  /// simplest way of using it is through the \c digraphCopy() function.
440 441
  ///
441 442
  /// This class not only make a copy of a digraph, but it can create
442 443
  /// references and cross references between the nodes and arcs of
443 444
  /// the two digraphs, and it can copy maps to use with the newly created
444 445
  /// digraph.
445 446
  ///
446 447
  /// To make a copy from a digraph, first an instance of DigraphCopy
447 448
  /// should be created, then the data belongs to the digraph should
448 449
  /// assigned to copy. In the end, the \c run() member should be
449 450
  /// called.
450 451
  ///
451 452
  /// The next code copies a digraph with several data:
452 453
  ///\code
453 454
  ///  DigraphCopy<OrigGraph, NewGraph> cg(orig_graph, new_graph);
454 455
  ///  // Create references for the nodes
455 456
  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
456 457
  ///  cg.nodeRef(nr);
457 458
  ///  // Create cross references (inverse) for the arcs
458 459
  ///  NewGraph::ArcMap<OrigGraph::Arc> acr(new_graph);
459 460
  ///  cg.arcCrossRef(acr);
460 461
  ///  // Copy an arc map
461 462
  ///  OrigGraph::ArcMap<double> oamap(orig_graph);
462 463
  ///  NewGraph::ArcMap<double> namap(new_graph);
463 464
  ///  cg.arcMap(oamap, namap);
464 465
  ///  // Copy a node
465 466
  ///  OrigGraph::Node on;
466 467
  ///  NewGraph::Node nn;
467 468
  ///  cg.node(on, nn);
468 469
  ///  // Execute copying
469 470
  ///  cg.run();
470 471
  ///\endcode
471 472
  template <typename From, typename To>
472 473
  class DigraphCopy {
473 474
  private:
474 475

	
475 476
    typedef typename From::Node Node;
476 477
    typedef typename From::NodeIt NodeIt;
477 478
    typedef typename From::Arc Arc;
478 479
    typedef typename From::ArcIt ArcIt;
479 480

	
480 481
    typedef typename To::Node TNode;
481 482
    typedef typename To::Arc TArc;
482 483

	
483 484
    typedef typename From::template NodeMap<TNode> NodeRefMap;
484 485
    typedef typename From::template ArcMap<TArc> ArcRefMap;
485 486

	
486 487
  public:
487 488

	
488 489
    /// \brief Constructor of DigraphCopy.
489 490
    ///
490 491
    /// Constructor of DigraphCopy for copying the content of the
491 492
    /// \c from digraph into the \c to digraph.
492 493
    DigraphCopy(const From& from, To& to)
493 494
      : _from(from), _to(to) {}
494 495

	
495 496
    /// \brief Destructor of DigraphCopy
496 497
    ///
497 498
    /// Destructor of DigraphCopy.
498 499
    ~DigraphCopy() {
499 500
      for (int i = 0; i < int(_node_maps.size()); ++i) {
500 501
        delete _node_maps[i];
501 502
      }
502 503
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
503 504
        delete _arc_maps[i];
504 505
      }
505 506

	
506 507
    }
507 508

	
508 509
    /// \brief Copy the node references into the given map.
509 510
    ///
510 511
    /// This function copies the node references into the given map.
511 512
    /// The parameter should be a map, whose key type is the Node type of
512 513
    /// the source digraph, while the value type is the Node type of the
513 514
    /// destination digraph.
514 515
    template <typename NodeRef>
515 516
    DigraphCopy& nodeRef(NodeRef& map) {
516 517
      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
517 518
                           NodeRefMap, NodeRef>(map));
518 519
      return *this;
519 520
    }
520 521

	
521 522
    /// \brief Copy the node cross references into the given map.
522 523
    ///
523 524
    /// This function copies the node cross references (reverse references)
524 525
    /// into the given map. The parameter should be a map, whose key type
525 526
    /// is the Node type of the destination digraph, while the value type is
526 527
    /// the Node type of the source digraph.
527 528
    template <typename NodeCrossRef>
528 529
    DigraphCopy& nodeCrossRef(NodeCrossRef& map) {
529 530
      _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node,
530 531
                           NodeRefMap, NodeCrossRef>(map));
531 532
      return *this;
532 533
    }
533 534

	
534 535
    /// \brief Make a copy of the given node map.
535 536
    ///
536 537
    /// This function makes a copy of the given node map for the newly
537 538
    /// created digraph.
538 539
    /// The key type of the new map \c tmap should be the Node type of the
539 540
    /// destination digraph, and the key type of the original map \c map
540 541
    /// should be the Node type of the source digraph.
541 542
    template <typename FromMap, typename ToMap>
542 543
    DigraphCopy& nodeMap(const FromMap& map, ToMap& tmap) {
543 544
      _node_maps.push_back(new _core_bits::MapCopy<From, Node,
544 545
                           NodeRefMap, FromMap, ToMap>(map, tmap));
545 546
      return *this;
546 547
    }
547 548

	
548 549
    /// \brief Make a copy of the given node.
549 550
    ///
550 551
    /// This function makes a copy of the given node.
551 552
    DigraphCopy& node(const Node& node, TNode& tnode) {
552 553
      _node_maps.push_back(new _core_bits::ItemCopy<From, Node,
553 554
                           NodeRefMap, TNode>(node, tnode));
554 555
      return *this;
555 556
    }
556 557

	
557 558
    /// \brief Copy the arc references into the given map.
558 559
    ///
559 560
    /// This function copies the arc references into the given map.
560 561
    /// The parameter should be a map, whose key type is the Arc type of
561 562
    /// the source digraph, while the value type is the Arc type of the
562 563
    /// destination digraph.
563 564
    template <typename ArcRef>
564 565
    DigraphCopy& arcRef(ArcRef& map) {
565 566
      _arc_maps.push_back(new _core_bits::RefCopy<From, Arc,
566 567
                          ArcRefMap, ArcRef>(map));
567 568
      return *this;
568 569
    }
569 570

	
570 571
    /// \brief Copy the arc cross references into the given map.
571 572
    ///
572 573
    /// This function copies the arc cross references (reverse references)
573 574
    /// into the given map. The parameter should be a map, whose key type
574 575
    /// is the Arc type of the destination digraph, while the value type is
575 576
    /// the Arc type of the source digraph.
576 577
    template <typename ArcCrossRef>
577 578
    DigraphCopy& arcCrossRef(ArcCrossRef& map) {
578 579
      _arc_maps.push_back(new _core_bits::CrossRefCopy<From, Arc,
579 580
                          ArcRefMap, ArcCrossRef>(map));
580 581
      return *this;
581 582
    }
582 583

	
583 584
    /// \brief Make a copy of the given arc map.
584 585
    ///
585 586
    /// This function makes a copy of the given arc map for the newly
586 587
    /// created digraph.
587 588
    /// The key type of the new map \c tmap should be the Arc type of the
588 589
    /// destination digraph, and the key type of the original map \c map
589 590
    /// should be the Arc type of the source digraph.
590 591
    template <typename FromMap, typename ToMap>
591 592
    DigraphCopy& arcMap(const FromMap& map, ToMap& tmap) {
592 593
      _arc_maps.push_back(new _core_bits::MapCopy<From, Arc,
593 594
                          ArcRefMap, FromMap, ToMap>(map, tmap));
594 595
      return *this;
595 596
    }
596 597

	
597 598
    /// \brief Make a copy of the given arc.
598 599
    ///
599 600
    /// This function makes a copy of the given arc.
600 601
    DigraphCopy& arc(const Arc& arc, TArc& tarc) {
601 602
      _arc_maps.push_back(new _core_bits::ItemCopy<From, Arc,
602 603
                          ArcRefMap, TArc>(arc, tarc));
603 604
      return *this;
604 605
    }
605 606

	
606 607
    /// \brief Execute copying.
607 608
    ///
608 609
    /// This function executes the copying of the digraph along with the
609 610
    /// copying of the assigned data.
610 611
    void run() {
611 612
      NodeRefMap nodeRefMap(_from);
612 613
      ArcRefMap arcRefMap(_from);
613 614
      _core_bits::DigraphCopySelector<To>::
614 615
        copy(_from, _to, nodeRefMap, arcRefMap);
615 616
      for (int i = 0; i < int(_node_maps.size()); ++i) {
616 617
        _node_maps[i]->copy(_from, nodeRefMap);
617 618
      }
618 619
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
619 620
        _arc_maps[i]->copy(_from, arcRefMap);
620 621
      }
621 622
    }
622 623

	
623 624
  protected:
624 625

	
625 626
    const From& _from;
626 627
    To& _to;
627 628

	
628 629
    std::vector<_core_bits::MapCopyBase<From, Node, NodeRefMap>* >
629 630
      _node_maps;
630 631

	
631 632
    std::vector<_core_bits::MapCopyBase<From, Arc, ArcRefMap>* >
632 633
      _arc_maps;
633 634

	
634 635
  };
635 636

	
636 637
  /// \brief Copy a digraph to another digraph.
637 638
  ///
638 639
  /// This function copies a digraph to another digraph.
639 640
  /// The complete usage of it is detailed in the DigraphCopy class, but
640 641
  /// a short example shows a basic work:
641 642
  ///\code
642 643
  /// digraphCopy(src, trg).nodeRef(nr).arcCrossRef(acr).run();
643 644
  ///\endcode
644 645
  ///
645 646
  /// After the copy the \c nr map will contain the mapping from the
646 647
  /// nodes of the \c from digraph to the nodes of the \c to digraph and
647 648
  /// \c acr will contain the mapping from the arcs of the \c to digraph
648 649
  /// to the arcs of the \c from digraph.
649 650
  ///
650 651
  /// \see DigraphCopy
651 652
  template <typename From, typename To>
652 653
  DigraphCopy<From, To> digraphCopy(const From& from, To& to) {
653 654
    return DigraphCopy<From, To>(from, to);
654 655
  }
655 656

	
656 657
  /// \brief Class to copy a graph.
657 658
  ///
658 659
  /// Class to copy a graph to another graph (duplicate a graph). The
659 660
  /// simplest way of using it is through the \c graphCopy() function.
660 661
  ///
661 662
  /// This class not only make a copy of a graph, but it can create
662 663
  /// references and cross references between the nodes, edges and arcs of
663 664
  /// the two graphs, and it can copy maps for using with the newly created
664 665
  /// graph.
665 666
  ///
666 667
  /// To make a copy from a graph, first an instance of GraphCopy
667 668
  /// should be created, then the data belongs to the graph should
668 669
  /// assigned to copy. In the end, the \c run() member should be
669 670
  /// called.
670 671
  ///
671 672
  /// The next code copies a graph with several data:
672 673
  ///\code
673 674
  ///  GraphCopy<OrigGraph, NewGraph> cg(orig_graph, new_graph);
674 675
  ///  // Create references for the nodes
675 676
  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
676 677
  ///  cg.nodeRef(nr);
677 678
  ///  // Create cross references (inverse) for the edges
678 679
  ///  NewGraph::EdgeMap<OrigGraph::Edge> ecr(new_graph);
679 680
  ///  cg.edgeCrossRef(ecr);
680 681
  ///  // Copy an edge map
681 682
  ///  OrigGraph::EdgeMap<double> oemap(orig_graph);
682 683
  ///  NewGraph::EdgeMap<double> nemap(new_graph);
683 684
  ///  cg.edgeMap(oemap, nemap);
684 685
  ///  // Copy a node
685 686
  ///  OrigGraph::Node on;
686 687
  ///  NewGraph::Node nn;
687 688
  ///  cg.node(on, nn);
688 689
  ///  // Execute copying
689 690
  ///  cg.run();
690 691
  ///\endcode
691 692
  template <typename From, typename To>
692 693
  class GraphCopy {
693 694
  private:
694 695

	
695 696
    typedef typename From::Node Node;
696 697
    typedef typename From::NodeIt NodeIt;
697 698
    typedef typename From::Arc Arc;
698 699
    typedef typename From::ArcIt ArcIt;
699 700
    typedef typename From::Edge Edge;
700 701
    typedef typename From::EdgeIt EdgeIt;
701 702

	
702 703
    typedef typename To::Node TNode;
703 704
    typedef typename To::Arc TArc;
704 705
    typedef typename To::Edge TEdge;
705 706

	
706 707
    typedef typename From::template NodeMap<TNode> NodeRefMap;
707 708
    typedef typename From::template EdgeMap<TEdge> EdgeRefMap;
708 709

	
709 710
    struct ArcRefMap {
710 711
      ArcRefMap(const From& from, const To& to,
711 712
                const EdgeRefMap& edge_ref, const NodeRefMap& node_ref)
712 713
        : _from(from), _to(to),
713 714
          _edge_ref(edge_ref), _node_ref(node_ref) {}
714 715

	
715 716
      typedef typename From::Arc Key;
716 717
      typedef typename To::Arc Value;
717 718

	
718 719
      Value operator[](const Key& key) const {
719 720
        bool forward = _from.u(key) != _from.v(key) ?
720 721
          _node_ref[_from.source(key)] ==
721 722
          _to.source(_to.direct(_edge_ref[key], true)) :
722 723
          _from.direction(key);
723 724
        return _to.direct(_edge_ref[key], forward);
724 725
      }
725 726

	
726 727
      const From& _from;
727 728
      const To& _to;
728 729
      const EdgeRefMap& _edge_ref;
729 730
      const NodeRefMap& _node_ref;
730 731
    };
731 732

	
732 733
  public:
733 734

	
734 735
    /// \brief Constructor of GraphCopy.
735 736
    ///
736 737
    /// Constructor of GraphCopy for copying the content of the
737 738
    /// \c from graph into the \c to graph.
738 739
    GraphCopy(const From& from, To& to)
739 740
      : _from(from), _to(to) {}
740 741

	
741 742
    /// \brief Destructor of GraphCopy
742 743
    ///
743 744
    /// Destructor of GraphCopy.
744 745
    ~GraphCopy() {
745 746
      for (int i = 0; i < int(_node_maps.size()); ++i) {
746 747
        delete _node_maps[i];
747 748
      }
748 749
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
749 750
        delete _arc_maps[i];
750 751
      }
751 752
      for (int i = 0; i < int(_edge_maps.size()); ++i) {
752 753
        delete _edge_maps[i];
753 754
      }
754 755
    }
755 756

	
756 757
    /// \brief Copy the node references into the given map.
757 758
    ///
758 759
    /// This function copies the node references into the given map.
759 760
    /// The parameter should be a map, whose key type is the Node type of
760 761
    /// the source graph, while the value type is the Node type of the
761 762
    /// destination graph.
762 763
    template <typename NodeRef>
763 764
    GraphCopy& nodeRef(NodeRef& map) {
764 765
      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
765 766
                           NodeRefMap, NodeRef>(map));
766 767
      return *this;
767 768
    }
768 769

	
769 770
    /// \brief Copy the node cross references into the given map.
770 771
    ///
771 772
    /// This function copies the node cross references (reverse references)
772 773
    /// into the given map. The parameter should be a map, whose key type
773 774
    /// is the Node type of the destination graph, while the value type is
774 775
    /// the Node type of the source graph.
775 776
    template <typename NodeCrossRef>
776 777
    GraphCopy& nodeCrossRef(NodeCrossRef& map) {
777 778
      _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node,
778 779
                           NodeRefMap, NodeCrossRef>(map));
779 780
      return *this;
780 781
    }
781 782

	
782 783
    /// \brief Make a copy of the given node map.
783 784
    ///
784 785
    /// This function makes a copy of the given node map for the newly
785 786
    /// created graph.
786 787
    /// The key type of the new map \c tmap should be the Node type of the
787 788
    /// destination graph, and the key type of the original map \c map
788 789
    /// should be the Node type of the source graph.
789 790
    template <typename FromMap, typename ToMap>
790 791
    GraphCopy& nodeMap(const FromMap& map, ToMap& tmap) {
791 792
      _node_maps.push_back(new _core_bits::MapCopy<From, Node,
792 793
                           NodeRefMap, FromMap, ToMap>(map, tmap));
793 794
      return *this;
794 795
    }
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
#ifndef LEMON_DFS_H
20 20
#define LEMON_DFS_H
21 21

	
22 22
///\ingroup search
23 23
///\file
24 24
///\brief DFS algorithm.
25 25

	
26 26
#include <lemon/list_graph.h>
27 27
#include <lemon/bits/path_dump.h>
28 28
#include <lemon/core.h>
29 29
#include <lemon/error.h>
30
#include <lemon/assert.h>
31 30
#include <lemon/maps.h>
32 31
#include <lemon/path.h>
33 32

	
34 33
namespace lemon {
35 34

	
36 35
  ///Default traits class of Dfs class.
37 36

	
38 37
  ///Default traits class of Dfs class.
39 38
  ///\tparam GR Digraph type.
40 39
  template<class GR>
41 40
  struct DfsDefaultTraits
42 41
  {
43 42
    ///The type of the digraph the algorithm runs on.
44 43
    typedef GR Digraph;
45 44

	
46 45
    ///\brief The type of the map that stores the predecessor
47 46
    ///arcs of the %DFS paths.
48 47
    ///
49 48
    ///The type of the map that stores the predecessor
50 49
    ///arcs of the %DFS paths.
51 50
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
52 51
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
53 52
    ///Instantiates a PredMap.
54 53

	
55 54
    ///This function instantiates a PredMap.
56 55
    ///\param g is the digraph, to which we would like to define the
57 56
    ///PredMap.
58 57
    static PredMap *createPredMap(const Digraph &g)
59 58
    {
60 59
      return new PredMap(g);
61 60
    }
62 61

	
63 62
    ///The type of the map that indicates which nodes are processed.
64 63

	
65 64
    ///The type of the map that indicates which nodes are processed.
66 65
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
67 66
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
68 67
    ///Instantiates a ProcessedMap.
69 68

	
70 69
    ///This function instantiates a ProcessedMap.
71 70
    ///\param g is the digraph, to which
72 71
    ///we would like to define the ProcessedMap
73 72
#ifdef DOXYGEN
74 73
    static ProcessedMap *createProcessedMap(const Digraph &g)
75 74
#else
76 75
    static ProcessedMap *createProcessedMap(const Digraph &)
77 76
#endif
78 77
    {
79 78
      return new ProcessedMap();
80 79
    }
81 80

	
82 81
    ///The type of the map that indicates which nodes are reached.
83 82

	
84 83
    ///The type of the map that indicates which nodes are reached.
85 84
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
86 85
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
87 86
    ///Instantiates a ReachedMap.
88 87

	
89 88
    ///This function instantiates a ReachedMap.
90 89
    ///\param g is the digraph, to which
91 90
    ///we would like to define the ReachedMap.
92 91
    static ReachedMap *createReachedMap(const Digraph &g)
93 92
    {
94 93
      return new ReachedMap(g);
95 94
    }
96 95

	
97 96
    ///The type of the map that stores the distances of the nodes.
98 97

	
99 98
    ///The type of the map that stores the distances of the nodes.
100 99
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
101 100
    typedef typename Digraph::template NodeMap<int> DistMap;
102 101
    ///Instantiates a DistMap.
103 102

	
104 103
    ///This function instantiates a DistMap.
105 104
    ///\param g is the digraph, to which we would like to define the
106 105
    ///DistMap.
107 106
    static DistMap *createDistMap(const Digraph &g)
108 107
    {
109 108
      return new DistMap(g);
110 109
    }
111 110
  };
112 111

	
113 112
  ///%DFS algorithm class.
114 113

	
115 114
  ///\ingroup search
116 115
  ///This class provides an efficient implementation of the %DFS algorithm.
117 116
  ///
118 117
  ///There is also a \ref dfs() "function-type interface" for the DFS
119 118
  ///algorithm, which is convenient in the simplier cases and it can be
120 119
  ///used easier.
121 120
  ///
122 121
  ///\tparam GR The type of the digraph the algorithm runs on.
123 122
  ///The default value is \ref ListDigraph. The value of GR is not used
124 123
  ///directly by \ref Dfs, it is only passed to \ref DfsDefaultTraits.
125 124
  ///\tparam TR Traits class to set various data types used by the algorithm.
126 125
  ///The default traits class is
127 126
  ///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
128 127
  ///See \ref DfsDefaultTraits for the documentation of
129 128
  ///a Dfs traits class.
130 129
#ifdef DOXYGEN
131 130
  template <typename GR,
132 131
            typename TR>
133 132
#else
134 133
  template <typename GR=ListDigraph,
135 134
            typename TR=DfsDefaultTraits<GR> >
136 135
#endif
137 136
  class Dfs {
138 137
  public:
139 138

	
140 139
    ///The type of the digraph the algorithm runs on.
141 140
    typedef typename TR::Digraph Digraph;
142 141

	
143 142
    ///\brief The type of the map that stores the predecessor arcs of the
144 143
    ///DFS paths.
145 144
    typedef typename TR::PredMap PredMap;
146 145
    ///The type of the map that stores the distances of the nodes.
147 146
    typedef typename TR::DistMap DistMap;
148 147
    ///The type of the map that indicates which nodes are reached.
149 148
    typedef typename TR::ReachedMap ReachedMap;
150 149
    ///The type of the map that indicates which nodes are processed.
151 150
    typedef typename TR::ProcessedMap ProcessedMap;
152 151
    ///The type of the paths.
153 152
    typedef PredMapPath<Digraph, PredMap> Path;
154 153

	
155 154
    ///The traits class.
156 155
    typedef TR Traits;
157 156

	
158 157
  private:
159 158

	
160 159
    typedef typename Digraph::Node Node;
161 160
    typedef typename Digraph::NodeIt NodeIt;
162 161
    typedef typename Digraph::Arc Arc;
163 162
    typedef typename Digraph::OutArcIt OutArcIt;
164 163

	
165 164
    //Pointer to the underlying digraph.
166 165
    const Digraph *G;
167 166
    //Pointer to the map of predecessor arcs.
168 167
    PredMap *_pred;
169 168
    //Indicates if _pred is locally allocated (true) or not.
170 169
    bool local_pred;
171 170
    //Pointer to the map of distances.
172 171
    DistMap *_dist;
173 172
    //Indicates if _dist is locally allocated (true) or not.
174 173
    bool local_dist;
175 174
    //Pointer to the map of reached status of the nodes.
176 175
    ReachedMap *_reached;
177 176
    //Indicates if _reached is locally allocated (true) or not.
178 177
    bool local_reached;
179 178
    //Pointer to the map of processed status of the nodes.
180 179
    ProcessedMap *_processed;
181 180
    //Indicates if _processed is locally allocated (true) or not.
182 181
    bool local_processed;
183 182

	
184 183
    std::vector<typename Digraph::OutArcIt> _stack;
185 184
    int _stack_head;
186 185

	
187 186
    //Creates the maps if necessary.
188 187
    void create_maps()
189 188
    {
190 189
      if(!_pred) {
191 190
        local_pred = true;
192 191
        _pred = Traits::createPredMap(*G);
193 192
      }
194 193
      if(!_dist) {
195 194
        local_dist = true;
196 195
        _dist = Traits::createDistMap(*G);
197 196
      }
198 197
      if(!_reached) {
199 198
        local_reached = true;
200 199
        _reached = Traits::createReachedMap(*G);
201 200
      }
202 201
      if(!_processed) {
203 202
        local_processed = true;
204 203
        _processed = Traits::createProcessedMap(*G);
205 204
      }
206 205
    }
207 206

	
208 207
  protected:
209 208

	
210 209
    Dfs() {}
211 210

	
212 211
  public:
213 212

	
214 213
    typedef Dfs Create;
215 214

	
216 215
    ///\name Named template parameters
217 216

	
218 217
    ///@{
219 218

	
220 219
    template <class T>
221 220
    struct SetPredMapTraits : public Traits {
222 221
      typedef T PredMap;
223 222
      static PredMap *createPredMap(const Digraph &)
224 223
      {
225 224
        LEMON_ASSERT(false, "PredMap is not initialized");
226 225
        return 0; // ignore warnings
227 226
      }
228 227
    };
229 228
    ///\brief \ref named-templ-param "Named parameter" for setting
230 229
    ///PredMap type.
231 230
    ///
232 231
    ///\ref named-templ-param "Named parameter" for setting
233 232
    ///PredMap type.
234 233
    template <class T>
235 234
    struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
236 235
      typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
237 236
    };
238 237

	
239 238
    template <class T>
240 239
    struct SetDistMapTraits : public Traits {
241 240
      typedef T DistMap;
242 241
      static DistMap *createDistMap(const Digraph &)
243 242
      {
244 243
        LEMON_ASSERT(false, "DistMap is not initialized");
245 244
        return 0; // ignore warnings
246 245
      }
247 246
    };
248 247
    ///\brief \ref named-templ-param "Named parameter" for setting
249 248
    ///DistMap type.
250 249
    ///
251 250
    ///\ref named-templ-param "Named parameter" for setting
252 251
    ///DistMap type.
253 252
    template <class T>
254 253
    struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
255 254
      typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
256 255
    };
257 256

	
258 257
    template <class T>
259 258
    struct SetReachedMapTraits : public Traits {
260 259
      typedef T ReachedMap;
261 260
      static ReachedMap *createReachedMap(const Digraph &)
262 261
      {
263 262
        LEMON_ASSERT(false, "ReachedMap is not initialized");
264 263
        return 0; // ignore warnings
265 264
      }
266 265
    };
267 266
    ///\brief \ref named-templ-param "Named parameter" for setting
268 267
    ///ReachedMap type.
269 268
    ///
270 269
    ///\ref named-templ-param "Named parameter" for setting
271 270
    ///ReachedMap type.
272 271
    template <class T>
273 272
    struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
274 273
      typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
275 274
    };
276 275

	
277 276
    template <class T>
278 277
    struct SetProcessedMapTraits : public Traits {
279 278
      typedef T ProcessedMap;
280 279
      static ProcessedMap *createProcessedMap(const Digraph &)
281 280
      {
282 281
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
283 282
        return 0; // ignore warnings
284 283
      }
285 284
    };
286 285
    ///\brief \ref named-templ-param "Named parameter" for setting
287 286
    ///ProcessedMap type.
288 287
    ///
289 288
    ///\ref named-templ-param "Named parameter" for setting
290 289
    ///ProcessedMap type.
291 290
    template <class T>
292 291
    struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
293 292
      typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
294 293
    };
295 294

	
296 295
    struct SetStandardProcessedMapTraits : public Traits {
297 296
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
298 297
      static ProcessedMap *createProcessedMap(const Digraph &g)
299 298
      {
300 299
        return new ProcessedMap(g);
301 300
      }
302 301
    };
303 302
    ///\brief \ref named-templ-param "Named parameter" for setting
304 303
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
305 304
    ///
306 305
    ///\ref named-templ-param "Named parameter" for setting
307 306
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
308 307
    ///If you don't set it explicitly, it will be automatically allocated.
309 308
    struct SetStandardProcessedMap :
310 309
      public Dfs< Digraph, SetStandardProcessedMapTraits > {
311 310
      typedef Dfs< Digraph, SetStandardProcessedMapTraits > Create;
312 311
    };
313 312

	
314 313
    ///@}
315 314

	
316 315
  public:
317 316

	
318 317
    ///Constructor.
319 318

	
320 319
    ///Constructor.
321 320
    ///\param g The digraph the algorithm runs on.
322 321
    Dfs(const Digraph &g) :
323 322
      G(&g),
324 323
      _pred(NULL), local_pred(false),
325 324
      _dist(NULL), local_dist(false),
326 325
      _reached(NULL), local_reached(false),
327 326
      _processed(NULL), local_processed(false)
328 327
    { }
329 328

	
330 329
    ///Destructor.
331 330
    ~Dfs()
332 331
    {
333 332
      if(local_pred) delete _pred;
334 333
      if(local_dist) delete _dist;
335 334
      if(local_reached) delete _reached;
336 335
      if(local_processed) delete _processed;
337 336
    }
338 337

	
339 338
    ///Sets the map that stores the predecessor arcs.
340 339

	
341 340
    ///Sets the map that stores the predecessor arcs.
342 341
    ///If you don't use this function before calling \ref run(),
343 342
    ///it will allocate one. The destructor deallocates this
344 343
    ///automatically allocated map, of course.
345 344
    ///\return <tt> (*this) </tt>
346 345
    Dfs &predMap(PredMap &m)
347 346
    {
348 347
      if(local_pred) {
349 348
        delete _pred;
350 349
        local_pred=false;
351 350
      }
352 351
      _pred = &m;
353 352
      return *this;
354 353
    }
355 354

	
356 355
    ///Sets the map that indicates which nodes are reached.
357 356

	
358 357
    ///Sets the map that indicates which nodes are reached.
359 358
    ///If you don't use this function before calling \ref run(),
360 359
    ///it will allocate one. The destructor deallocates this
361 360
    ///automatically allocated map, of course.
362 361
    ///\return <tt> (*this) </tt>
363 362
    Dfs &reachedMap(ReachedMap &m)
364 363
    {
365 364
      if(local_reached) {
366 365
        delete _reached;
367 366
        local_reached=false;
368 367
      }
369 368
      _reached = &m;
370 369
      return *this;
371 370
    }
372 371

	
373 372
    ///Sets the map that indicates which nodes are processed.
374 373

	
375 374
    ///Sets the map that indicates which nodes are processed.
376 375
    ///If you don't use this function before calling \ref run(),
377 376
    ///it will allocate one. The destructor deallocates this
378 377
    ///automatically allocated map, of course.
379 378
    ///\return <tt> (*this) </tt>
380 379
    Dfs &processedMap(ProcessedMap &m)
381 380
    {
382 381
      if(local_processed) {
383 382
        delete _processed;
384 383
        local_processed=false;
385 384
      }
386 385
      _processed = &m;
387 386
      return *this;
388 387
    }
389 388

	
390 389
    ///Sets the map that stores the distances of the nodes.
391 390

	
392 391
    ///Sets the map that stores the distances of the nodes calculated by
393 392
    ///the algorithm.
394 393
    ///If you don't use this function before calling \ref run(),
395 394
    ///it will allocate one. The destructor deallocates this
396 395
    ///automatically allocated map, of course.
397 396
    ///\return <tt> (*this) </tt>
398 397
    Dfs &distMap(DistMap &m)
399 398
    {
400 399
      if(local_dist) {
401 400
        delete _dist;
402 401
        local_dist=false;
403 402
      }
404 403
      _dist = &m;
405 404
      return *this;
406 405
    }
407 406

	
408 407
  public:
409 408

	
410 409
    ///\name Execution control
411 410
    ///The simplest way to execute the algorithm is to use
412 411
    ///one of the member functions called \ref lemon::Dfs::run() "run()".
413 412
    ///\n
414 413
    ///If you need more control on the execution, first you must call
415 414
    ///\ref lemon::Dfs::init() "init()", then you can add a source node
416 415
    ///with \ref lemon::Dfs::addSource() "addSource()".
417 416
    ///Finally \ref lemon::Dfs::start() "start()" will perform the
418 417
    ///actual path computation.
419 418

	
420 419
    ///@{
421 420

	
422 421
    ///Initializes the internal data structures.
423 422

	
424 423
    ///Initializes the internal data structures.
425 424
    ///
426 425
    void init()
427 426
    {
428 427
      create_maps();
429 428
      _stack.resize(countNodes(*G));
430 429
      _stack_head=-1;
431 430
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
432 431
        _pred->set(u,INVALID);
433 432
        _reached->set(u,false);
434 433
        _processed->set(u,false);
435 434
      }
436 435
    }
437 436

	
438 437
    ///Adds a new source node.
439 438

	
440 439
    ///Adds a new source node to the set of nodes to be processed.
441 440
    ///
442 441
    ///\pre The stack must be empty. (Otherwise the algorithm gives
443 442
    ///false results.)
444 443
    ///
445 444
    ///\warning Distances will be wrong (or at least strange) in case of
446 445
    ///multiple sources.
447 446
    void addSource(Node s)
448 447
    {
449 448
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
450 449
      if(!(*_reached)[s])
451 450
        {
452 451
          _reached->set(s,true);
453 452
          _pred->set(s,INVALID);
454 453
          OutArcIt e(*G,s);
455 454
          if(e!=INVALID) {
456 455
            _stack[++_stack_head]=e;
457 456
            _dist->set(s,_stack_head);
458 457
          }
459 458
          else {
460 459
            _processed->set(s,true);
461 460
            _dist->set(s,0);
462 461
          }
463 462
        }
464 463
    }
465 464

	
466 465
    ///Processes the next arc.
467 466

	
468 467
    ///Processes the next arc.
469 468
    ///
470 469
    ///\return The processed arc.
471 470
    ///
472 471
    ///\pre The stack must not be empty.
473 472
    Arc processNextArc()
474 473
    {
475 474
      Node m;
476 475
      Arc e=_stack[_stack_head];
477 476
      if(!(*_reached)[m=G->target(e)]) {
478 477
        _pred->set(m,e);
479 478
        _reached->set(m,true);
480 479
        ++_stack_head;
481 480
        _stack[_stack_head] = OutArcIt(*G, m);
482 481
        _dist->set(m,_stack_head);
483 482
      }
484 483
      else {
485 484
        m=G->source(e);
486 485
        ++_stack[_stack_head];
487 486
      }
488 487
      while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
489 488
        _processed->set(m,true);
490 489
        --_stack_head;
491 490
        if(_stack_head>=0) {
492 491
          m=G->source(_stack[_stack_head]);
493 492
          ++_stack[_stack_head];
494 493
        }
495 494
      }
496 495
      return e;
497 496
    }
498 497

	
499 498
    ///Next arc to be processed.
500 499

	
501 500
    ///Next arc to be processed.
502 501
    ///
503 502
    ///\return The next arc to be processed or \c INVALID if the stack
504 503
    ///is empty.
505 504
    OutArcIt nextArc() const
506 505
    {
507 506
      return _stack_head>=0?_stack[_stack_head]:INVALID;
508 507
    }
509 508

	
510 509
    ///\brief Returns \c false if there are nodes
511 510
    ///to be processed.
512 511
    ///
513 512
    ///Returns \c false if there are nodes
514 513
    ///to be processed in the queue (stack).
515 514
    bool emptyQueue() const { return _stack_head<0; }
516 515

	
517 516
    ///Returns the number of the nodes to be processed.
518 517

	
519 518
    ///Returns the number of the nodes to be processed in the queue (stack).
520 519
    int queueSize() const { return _stack_head+1; }
521 520

	
522 521
    ///Executes the algorithm.
523 522

	
524 523
    ///Executes the algorithm.
525 524
    ///
526 525
    ///This method runs the %DFS algorithm from the root node
527 526
    ///in order to compute the DFS path to each node.
528 527
    ///
529 528
    /// The algorithm computes
530 529
    ///- the %DFS tree,
531 530
    ///- the distance of each node from the root in the %DFS tree.
532 531
    ///
533 532
    ///\pre init() must be called and a root node should be
534 533
    ///added with addSource() before using this function.
535 534
    ///
536 535
    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
537 536
    ///\code
538 537
    ///  while ( !d.emptyQueue() ) {
539 538
    ///    d.processNextArc();
540 539
    ///  }
541 540
    ///\endcode
542 541
    void start()
543 542
    {
544 543
      while ( !emptyQueue() ) processNextArc();
545 544
    }
546 545

	
547 546
    ///Executes the algorithm until the given target node is reached.
548 547

	
549 548
    ///Executes the algorithm until the given target node is reached.
550 549
    ///
551 550
    ///This method runs the %DFS algorithm from the root node
552 551
    ///in order to compute the DFS path to \c t.
553 552
    ///
554 553
    ///The algorithm computes
555 554
    ///- the %DFS path to \c t,
556 555
    ///- the distance of \c t from the root in the %DFS tree.
557 556
    ///
558 557
    ///\pre init() must be called and a root node should be
559 558
    ///added with addSource() before using this function.
560 559
    void start(Node t)
561 560
    {
562 561
      while ( !emptyQueue() && G->target(_stack[_stack_head])!=t )
563 562
        processNextArc();
564 563
    }
565 564

	
566 565
    ///Executes the algorithm until a condition is met.
567 566

	
568 567
    ///Executes the algorithm until a condition is met.
569 568
    ///
570 569
    ///This method runs the %DFS algorithm from the root node
571 570
    ///until an arc \c a with <tt>am[a]</tt> true is found.
572 571
    ///
573 572
    ///\param am A \c bool (or convertible) arc map. The algorithm
574 573
    ///will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
575 574
    ///
576 575
    ///\return The reached arc \c a with <tt>am[a]</tt> true or
577 576
    ///\c INVALID if no such arc was found.
578 577
    ///
579 578
    ///\pre init() must be called and a root node should be
580 579
    ///added with addSource() before using this function.
581 580
    ///
582 581
    ///\warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
583 582
    ///not a node map.
584 583
    template<class ArcBoolMap>
585 584
    Arc start(const ArcBoolMap &am)
586 585
    {
587 586
      while ( !emptyQueue() && !am[_stack[_stack_head]] )
588 587
        processNextArc();
589 588
      return emptyQueue() ? INVALID : _stack[_stack_head];
590 589
    }
591 590

	
592 591
    ///Runs the algorithm from the given source node.
593 592

	
594 593
    ///This method runs the %DFS algorithm from node \c s
595 594
    ///in order to compute the DFS path to each node.
596 595
    ///
597 596
    ///The algorithm computes
598 597
    ///- the %DFS tree,
599 598
    ///- the distance of each node from the root in the %DFS tree.
600 599
    ///
601 600
    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
602 601
    ///\code
603 602
    ///  d.init();
604 603
    ///  d.addSource(s);
605 604
    ///  d.start();
606 605
    ///\endcode
607 606
    void run(Node s) {
608 607
      init();
609 608
      addSource(s);
610 609
      start();
611 610
    }
612 611

	
613 612
    ///Finds the %DFS path between \c s and \c t.
614 613

	
615 614
    ///This method runs the %DFS algorithm from node \c s
616 615
    ///in order to compute the DFS path to node \c t
617 616
    ///(it stops searching when \c t is processed)
618 617
    ///
619 618
    ///\return \c true if \c t is reachable form \c s.
620 619
    ///
621 620
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is
622 621
    ///just a shortcut of the following code.
623 622
    ///\code
624 623
    ///  d.init();
625 624
    ///  d.addSource(s);
626 625
    ///  d.start(t);
627 626
    ///\endcode
628 627
    bool run(Node s,Node t) {
629 628
      init();
630 629
      addSource(s);
631 630
      start(t);
632 631
      return reached(t);
633 632
    }
634 633

	
635 634
    ///Runs the algorithm to visit all nodes in the digraph.
636 635

	
637 636
    ///This method runs the %DFS algorithm in order to compute the
638 637
    ///%DFS path to each node.
639 638
    ///
640 639
    ///The algorithm computes
641 640
    ///- the %DFS tree,
642 641
    ///- the distance of each node from the root in the %DFS tree.
643 642
    ///
644 643
    ///\note <tt>d.run()</tt> is just a shortcut of the following code.
645 644
    ///\code
646 645
    ///  d.init();
647 646
    ///  for (NodeIt n(digraph); n != INVALID; ++n) {
648 647
    ///    if (!d.reached(n)) {
649 648
    ///      d.addSource(n);
650 649
    ///      d.start();
651 650
    ///    }
652 651
    ///  }
653 652
    ///\endcode
654 653
    void run() {
655 654
      init();
656 655
      for (NodeIt it(*G); it != INVALID; ++it) {
657 656
        if (!reached(it)) {
658 657
          addSource(it);
659 658
          start();
660 659
        }
661 660
      }
662 661
    }
663 662

	
664 663
    ///@}
665 664

	
666 665
    ///\name Query Functions
667 666
    ///The result of the %DFS algorithm can be obtained using these
668 667
    ///functions.\n
669 668
    ///Either \ref lemon::Dfs::run() "run()" or \ref lemon::Dfs::start()
670 669
    ///"start()" must be called before using them.
671 670

	
672 671
    ///@{
673 672

	
674 673
    ///The DFS path to a node.
675 674

	
676 675
    ///Returns the DFS path to a node.
677 676
    ///
678 677
    ///\warning \c t should be reachable from the root.
679 678
    ///
680 679
    ///\pre Either \ref run() or \ref start() must be called before
681 680
    ///using this function.
682 681
    Path path(Node t) const { return Path(*G, *_pred, t); }
683 682

	
684 683
    ///The distance of a node from the root.
685 684

	
686 685
    ///Returns the distance of a node from the root.
687 686
    ///
688 687
    ///\warning If node \c v is not reachable from the root, then
689 688
    ///the return value of this function is undefined.
690 689
    ///
691 690
    ///\pre Either \ref run() or \ref start() must be called before
692 691
    ///using this function.
693 692
    int dist(Node v) const { return (*_dist)[v]; }
694 693

	
695 694
    ///Returns the 'previous arc' of the %DFS tree for a node.
696 695

	
697 696
    ///This function returns the 'previous arc' of the %DFS tree for the
698 697
    ///node \c v, i.e. it returns the last arc of a %DFS path from the
699 698
    ///root to \c v. It is \c INVALID
700 699
    ///if \c v is not reachable from the root(s) or if \c v is a root.
701 700
    ///
702 701
    ///The %DFS tree used here is equal to the %DFS tree used in
703 702
    ///\ref predNode().
704 703
    ///
705 704
    ///\pre Either \ref run() or \ref start() must be called before using
706 705
    ///this function.
707 706
    Arc predArc(Node v) const { return (*_pred)[v];}
708 707

	
709 708
    ///Returns the 'previous node' of the %DFS tree.
710 709

	
711 710
    ///This function returns the 'previous node' of the %DFS
712 711
    ///tree for the node \c v, i.e. it returns the last but one node
713 712
    ///from a %DFS path from the root to \c v. It is \c INVALID
714 713
    ///if \c v is not reachable from the root(s) or if \c v is a root.
715 714
    ///
716 715
    ///The %DFS tree used here is equal to the %DFS tree used in
717 716
    ///\ref predArc().
718 717
    ///
719 718
    ///\pre Either \ref run() or \ref start() must be called before
720 719
    ///using this function.
721 720
    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
722 721
                                  G->source((*_pred)[v]); }
723 722

	
724 723
    ///\brief Returns a const reference to the node map that stores the
725 724
    ///distances of the nodes.
726 725
    ///
727 726
    ///Returns a const reference to the node map that stores the
728 727
    ///distances of the nodes calculated by the algorithm.
729 728
    ///
730 729
    ///\pre Either \ref run() or \ref init()
731 730
    ///must be called before using this function.
732 731
    const DistMap &distMap() const { return *_dist;}
733 732

	
734 733
    ///\brief Returns a const reference to the node map that stores the
735 734
    ///predecessor arcs.
736 735
    ///
737 736
    ///Returns a const reference to the node map that stores the predecessor
738 737
    ///arcs, which form the DFS tree.
739 738
    ///
740 739
    ///\pre Either \ref run() or \ref init()
741 740
    ///must be called before using this function.
742 741
    const PredMap &predMap() const { return *_pred;}
743 742

	
744 743
    ///Checks if a node is reachable from the root(s).
745 744

	
746 745
    ///Returns \c true if \c v is reachable from the root(s).
747 746
    ///\pre Either \ref run() or \ref start()
748 747
    ///must be called before using this function.
749 748
    bool reached(Node v) const { return (*_reached)[v]; }
750 749

	
751 750
    ///@}
752 751
  };
753 752

	
754 753
  ///Default traits class of dfs() function.
755 754

	
756 755
  ///Default traits class of dfs() function.
757 756
  ///\tparam GR Digraph type.
758 757
  template<class GR>
759 758
  struct DfsWizardDefaultTraits
760 759
  {
761 760
    ///The type of the digraph the algorithm runs on.
762 761
    typedef GR Digraph;
763 762

	
764 763
    ///\brief The type of the map that stores the predecessor
765 764
    ///arcs of the %DFS paths.
766 765
    ///
767 766
    ///The type of the map that stores the predecessor
768 767
    ///arcs of the %DFS paths.
769 768
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
770 769
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
771 770
    ///Instantiates a PredMap.
772 771

	
773 772
    ///This function instantiates a PredMap.
774 773
    ///\param g is the digraph, to which we would like to define the
775 774
    ///PredMap.
776 775
    static PredMap *createPredMap(const Digraph &g)
777 776
    {
778 777
      return new PredMap(g);
779 778
    }
780 779

	
781 780
    ///The type of the map that indicates which nodes are processed.
782 781

	
783 782
    ///The type of the map that indicates which nodes are processed.
784 783
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
785 784
    ///By default it is a NullMap.
786 785
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
787 786
    ///Instantiates a ProcessedMap.
788 787

	
789 788
    ///This function instantiates a ProcessedMap.
790 789
    ///\param g is the digraph, to which
791 790
    ///we would like to define the ProcessedMap.
792 791
#ifdef DOXYGEN
793 792
    static ProcessedMap *createProcessedMap(const Digraph &g)
794 793
#else
795 794
    static ProcessedMap *createProcessedMap(const Digraph &)
796 795
#endif
797 796
    {
798 797
      return new ProcessedMap();
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
#include <lemon/assert.h>
35 34
#include <lemon/core.h>
36 35

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

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

	
42 41
namespace lemon {
43 42

	
44 43
  namespace _reader_bits {
45 44

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

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

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

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

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

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

	
81 80
    };
82 81

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
333 332
      Functor _functor;
334 333

	
335 334
    public:
336 335

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

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

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

	
365 364
      Functor _functor;
366 365

	
367 366
    public:
368 367

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

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

	
389 388
  }
390 389

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

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

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

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

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

	
480 479
    typedef _Digraph Digraph;
481 480
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
482 481

	
483 482
  private:
484 483

	
485 484

	
486 485
    std::istream* _is;
487 486
    bool local_is;
488 487
    std::string _filename;
489 488

	
490 489
    Digraph& _digraph;
491 490

	
492 491
    std::string _nodes_caption;
493 492
    std::string _arcs_caption;
494 493
    std::string _attributes_caption;
495 494

	
496 495
    typedef std::map<std::string, Node> NodeIndex;
497 496
    NodeIndex _node_index;
498 497
    typedef std::map<std::string, Arc> ArcIndex;
499 498
    ArcIndex _arc_index;
500 499

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

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

	
509 508
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
510 509
      Attributes;
511 510
    Attributes _attributes;
512 511

	
513 512
    bool _use_nodes;
514 513
    bool _use_arcs;
515 514

	
516 515
    bool _skip_nodes;
517 516
    bool _skip_arcs;
518 517

	
519 518
    int line_num;
520 519
    std::istringstream line;
521 520

	
522 521
  public:
523 522

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

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

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

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

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

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

	
580 579
      if (local_is) {
581 580
        delete _is;
582 581
      }
583 582

	
584 583
    }
585 584

	
586 585
  private:
587 586

	
588 587
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
589 588
                                                  std::istream& is);
590 589
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
591 590
                                                  const std::string& fn);
592 591
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
593 592
                                                  const char *fn);
594 593

	
595 594
    DigraphReader(DigraphReader& other)
596 595
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
597 596
        _use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
598 597
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
599 598

	
600 599
      other._is = 0;
601 600
      other.local_is = false;
602 601

	
603 602
      _node_index.swap(other._node_index);
604 603
      _arc_index.swap(other._arc_index);
605 604

	
606 605
      _node_maps.swap(other._node_maps);
607 606
      _arc_maps.swap(other._arc_maps);
608 607
      _attributes.swap(other._attributes);
609 608

	
610 609
      _nodes_caption = other._nodes_caption;
611 610
      _arcs_caption = other._arcs_caption;
612 611
      _attributes_caption = other._attributes_caption;
613 612

	
614 613
    }
615 614

	
616 615
    DigraphReader& operator=(const DigraphReader&);
617 616

	
618 617
  public:
619 618

	
620 619
    /// \name Reading rules
621 620
    /// @{
622 621

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

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

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

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

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

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

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

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

	
723 722
    /// @}
724 723

	
725 724
    /// \name Select section by name
726 725
    /// @{
727 726

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

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

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

	
752 751
    /// @}
753 752

	
754 753
    /// \name Using previously constructed node or arc set
755 754
    /// @{
756 755

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

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

	
790 789
    /// \brief Use previously constructed arc set
791 790
    ///
792 791
    /// Use previously constructed arc set, and specify the arc
793 792
    /// label map.
794 793
    template <typename Map>
795 794
    DigraphReader& useArcs(const Map& map) {
796 795
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
797 796
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
798 797
      _use_arcs = true;
799 798
      _writer_bits::DefaultConverter<typename Map::Value> converter;
800 799
      for (ArcIt a(_digraph); a != INVALID; ++a) {
801 800
        _arc_index.insert(std::make_pair(converter(map[a]), a));
802 801
      }
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
#include <lemon/assert.h>
37 36
#include <lemon/core.h>
38 37
#include <lemon/maps.h>
39 38

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

	
43 42
namespace lemon {
44 43

	
45 44
  namespace _writer_bits {
46 45

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
320 319
      Functor _functor;
321 320

	
322 321
    public:
323 322

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

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

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

	
337 336
      Functor _functor;
338 337

	
339 338
    public:
340 339

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

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

	
349 348
  }
350 349

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

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

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

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

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

	
435 434
    typedef _Digraph Digraph;
436 435
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
437 436

	
438 437
  private:
439 438

	
440 439

	
441 440
    std::ostream* _os;
442 441
    bool local_os;
443 442

	
444 443
    const Digraph& _digraph;
445 444

	
446 445
    std::string _nodes_caption;
447 446
    std::string _arcs_caption;
448 447
    std::string _attributes_caption;
449 448

	
450 449
    typedef std::map<Node, std::string> NodeIndex;
451 450
    NodeIndex _node_index;
452 451
    typedef std::map<Arc, std::string> ArcIndex;
453 452
    ArcIndex _arc_index;
454 453

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

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

	
463 462
    typedef std::vector<std::pair<std::string,
464 463
      _writer_bits::ValueStorageBase*> > Attributes;
465 464
    Attributes _attributes;
466 465

	
467 466
    bool _skip_nodes;
468 467
    bool _skip_arcs;
469 468

	
470 469
  public:
471 470

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

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

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

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

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

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

	
523 522
      if (local_os) {
524 523
        delete _os;
525 524
      }
526 525
    }
527 526

	
528 527
  private:
529 528

	
530 529
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
531 530
                                                  std::ostream& os);
532 531
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
533 532
                                                  const std::string& fn);
534 533
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
535 534
                                                  const char *fn);
536 535

	
537 536
    DigraphWriter(DigraphWriter& other)
538 537
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
539 538
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
540 539

	
541 540
      other._os = 0;
542 541
      other.local_os = false;
543 542

	
544 543
      _node_index.swap(other._node_index);
545 544
      _arc_index.swap(other._arc_index);
546 545

	
547 546
      _node_maps.swap(other._node_maps);
548 547
      _arc_maps.swap(other._arc_maps);
549 548
      _attributes.swap(other._attributes);
550 549

	
551 550
      _nodes_caption = other._nodes_caption;
552 551
      _arcs_caption = other._arcs_caption;
553 552
      _attributes_caption = other._attributes_caption;
554 553
    }
555 554

	
556 555
    DigraphWriter& operator=(const DigraphWriter&);
557 556

	
558 557
  public:
559 558

	
560 559
    /// \name Writing rules
561 560
    /// @{
562 561

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

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

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

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

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

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

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

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

	
663 662
    /// \name Section captions
664 663
    /// @{
665 664

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

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

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

	
690 689
    /// \name Skipping section
691 690
    /// @{
692 691

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

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

	
711 710
    /// @}
712 711

	
713 712
  private:
714 713

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

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

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

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

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

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

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

	
785 784
      if (label == 0) {
786 785
        for (NodeIt n(_digraph); n != INVALID; ++n) {
787 786
          std::ostringstream os;
788 787
          os << _digraph.id(n);
789 788
          _node_index.insert(std::make_pair(n, os.str()));
790 789
        }
791 790
      } else {
792 791
        for (NodeIt n(_digraph); n != INVALID; ++n) {
793 792
          std::string value = label->get(n);
794 793
          _node_index.insert(std::make_pair(n, value));
795 794
        }
796 795
      }
797 796
    }
798 797

	
799 798
    void writeArcs() {
800 799
      _writer_bits::MapStorageBase<Arc>* label = 0;
801 800
      for (typename ArcMaps::iterator it = _arc_maps.begin();
802 801
           it != _arc_maps.end(); ++it) {
803 802
        if (it->first == "label") {
804 803
          label = it->second;
0 comments (0 inline)