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 768 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,
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_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
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.
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
0 comments (0 inline)