gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Simplifying exceptions - Using asserts instead of exceptions for unitialized parameters - Only the IO exceptions are used in the lemon - DataFormatError is renamed to FormatError - The IoError is used for file access errors
0 11 0
default
11 files changed with 380 insertions and 511 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\ingroup demos
20 20
///\file
21 21
///\brief Demonstrating graph input and output
22 22
///
23 23
/// This program gives an example of how to read and write a digraph
24 24
/// and additional maps from/to a stream or a file using the
25 25
/// \ref lgf-format "LGF" format.
26 26
///
27 27
/// The \c "digraph.lgf" file:
28 28
/// \include digraph.lgf
29 29
///
30 30
/// And the program which reads it and prints the digraph to the
31 31
/// standard output:
32 32
/// \include lgf_demo.cc
33 33

	
34 34
#include <iostream>
35 35
#include <lemon/smart_graph.h>
36 36
#include <lemon/lgf_reader.h>
37 37
#include <lemon/lgf_writer.h>
38 38

	
39 39
using namespace lemon;
40 40

	
41 41
int main() {
42 42
  SmartDigraph g;
43 43
  SmartDigraph::ArcMap<int> cap(g);
44 44
  SmartDigraph::Node s, t;
45 45

	
46 46
  try {
47 47
    digraphReader("digraph.lgf", g). // read the directed graph into g
48 48
      arcMap("capacity", cap).       // read the 'capacity' arc map into cap
49 49
      node("source", s).             // read 'source' node to s
50 50
      node("target", t).             // read 'target' node to t
51 51
      run();
52
  } catch (DataFormatError& error) { // check if there was any error
52
  } catch (Exception& error) { // check if there was any error
53 53
    std::cerr << "Error: " << error.what() << std::endl;
54 54
    return -1;
55 55
  }
56 56

	
57 57
  std::cout << "A digraph is read from 'digraph.lgf'." << std::endl;
58 58
  std::cout << "Number of nodes: " << countNodes(g) << std::endl;
59 59
  std::cout << "Number of arcs: " << countArcs(g) << std::endl;
60 60

	
61 61
  std::cout << "We can write it to the standard output:" << std::endl;
62 62

	
63 63
  digraphWriter(std::cout, g).     // write g to the standard output
64 64
    arcMap("capacity", cap).       // write cap into 'capacity'
65 65
    node("source", s).             // write s to 'source'
66 66
    node("target", t).             // write t to 'target'
67 67
    run();
68 68

	
69 69
  return 0;
70 70
}
Ignore white space 6 line context
... ...
@@ -121,265 +121,266 @@
121 121
    ///Constructor
122 122
    ArgParser(int argc, const char **argv);
123 123

	
124 124
    ~ArgParser();
125 125

	
126 126
    ///\name Options
127 127
    ///
128 128

	
129 129
    ///@{
130 130

	
131 131
    ///Add a new integer type option
132 132

	
133 133
    ///Add a new integer type option.
134 134
    ///\param name The name of the option. The leading '-' must be omitted.
135 135
    ///\param help A help string.
136 136
    ///\param value A default value for the option.
137 137
    ///\param obl Indicate if the option is mandatory.
138 138
    ArgParser &intOption(const std::string &name,
139 139
                    const std::string &help,
140 140
                    int value=0, bool obl=false);
141 141

	
142 142
    ///Add a new floating point type option
143 143

	
144 144
    ///Add a new floating point type option.
145 145
    ///\param name The name of the option. The leading '-' must be omitted.
146 146
    ///\param help A help string.
147 147
    ///\param value A default value for the option.
148 148
    ///\param obl Indicate if the option is mandatory.
149 149
    ArgParser &doubleOption(const std::string &name,
150 150
                      const std::string &help,
151 151
                      double value=0, bool obl=false);
152 152

	
153 153
    ///Add a new bool type option
154 154

	
155 155
    ///Add a new bool type option.
156 156
    ///\param name The name of the option. The leading '-' must be omitted.
157 157
    ///\param help A help string.
158 158
    ///\param value A default value for the option.
159 159
    ///\param obl Indicate if the option is mandatory.
160 160
    ///\note A mandatory bool obtion is of very little use.
161 161
    ArgParser &boolOption(const std::string &name,
162 162
                      const std::string &help,
163 163
                      bool value=false, bool obl=false);
164 164

	
165 165
    ///Add a new string type option
166 166

	
167 167
    ///Add a new string type option.
168 168
    ///\param name The name of the option. The leading '-' must be omitted.
169 169
    ///\param help A help string.
170 170
    ///\param value A default value for the option.
171 171
    ///\param obl Indicate if the option is mandatory.
172 172
    ArgParser &stringOption(const std::string &name,
173 173
                      const std::string &help,
174 174
                      std::string value="", bool obl=false);
175 175

	
176 176
    ///Give help string for non-parsed arguments.
177 177

	
178 178
    ///With this function you can give help string for non-parsed arguments.
179 179
    ///The parameter \c name will be printed in the short usage line, while
180 180
    ///\c help gives a more detailed description.
181 181
    ArgParser &other(const std::string &name,
182 182
                     const std::string &help="");
183 183

	
184 184
    ///@}
185 185

	
186 186
    ///\name Options with External Storage
187 187
    ///Using this functions, the value of the option will be directly written
188 188
    ///into a variable once the option appears in the command line.
189 189

	
190 190
    ///@{
191 191

	
192 192
    ///Add a new integer type option with a storage reference
193 193

	
194 194
    ///Add a new integer type option with a storage reference.
195 195
    ///\param name The name of the option. The leading '-' must be omitted.
196 196
    ///\param help A help string.
197 197
    ///\param obl Indicate if the option is mandatory.
198 198
    ///\retval ref The value of the argument will be written to this variable.
199 199
    ArgParser &refOption(const std::string &name,
200 200
                    const std::string &help,
201 201
                    int &ref, bool obl=false);
202 202

	
203 203
    ///Add a new floating type option with a storage reference
204 204

	
205 205
    ///Add a new floating type option with a storage reference.
206 206
    ///\param name The name of the option. The leading '-' must be omitted.
207 207
    ///\param help A help string.
208 208
    ///\param obl Indicate if the option is mandatory.
209 209
    ///\retval ref The value of the argument will be written to this variable.
210 210
    ArgParser &refOption(const std::string &name,
211 211
                      const std::string &help,
212 212
                      double &ref, bool obl=false);
213 213

	
214 214
    ///Add a new bool type option with a storage reference
215 215

	
216 216
    ///Add a new bool type option with a storage reference.
217 217
    ///\param name The name of the option. The leading '-' must be omitted.
218 218
    ///\param help A help string.
219 219
    ///\param obl Indicate if the option is mandatory.
220 220
    ///\retval ref The value of the argument will be written to this variable.
221 221
    ///\note A mandatory bool obtion is of very little use.
222 222
    ArgParser &refOption(const std::string &name,
223 223
                      const std::string &help,
224 224
                      bool &ref, bool obl=false);
225 225

	
226 226
    ///Add a new string type option with a storage reference
227 227

	
228 228
    ///Add a new string type option with a storage reference.
229 229
    ///\param name The name of the option. The leading '-' must be omitted.
230 230
    ///\param help A help string.
231 231
    ///\param obl Indicate if the option is mandatory.
232 232
    ///\retval ref The value of the argument will be written to this variable.
233 233
    ArgParser &refOption(const std::string &name,
234 234
                      const std::string &help,
235 235
                      std::string &ref, bool obl=false);
236 236

	
237 237
    ///@}
238 238

	
239 239
    ///\name Option Groups and Synonyms
240 240
    ///
241 241

	
242 242
    ///@{
243 243

	
244 244
    ///Bundle some options into a group
245 245

	
246 246
    /// You can group some option by calling this function repeatedly for each
247 247
    /// option to be grouped with the same groupname.
248 248
    ///\param group The group name.
249 249
    ///\param opt The option name.
250 250
    ArgParser &optionGroup(const std::string &group,
251 251
                           const std::string &opt);
252 252

	
253 253
    ///Make the members of a group exclusive
254 254

	
255 255
    ///If you call this function for a group, than at most one of them can be
256 256
    ///given at the same time.
257 257
    ArgParser &onlyOneGroup(const std::string &group);
258 258

	
259 259
    ///Make a group mandatory
260 260

	
261 261
    ///Using this function, at least one of the members of \c group
262 262
    ///must be given.
263 263
    ArgParser &mandatoryGroup(const std::string &group);
264 264

	
265 265
    ///Create synonym to an option
266 266

	
267 267
    ///With this function you can create a synonym \c syn of the
268 268
    ///option \c opt.
269 269
    ArgParser &synonym(const std::string &syn,
270 270
                           const std::string &opt);
271 271

	
272 272
    ///@}
273 273

	
274 274
  private:
275 275
    void show(std::ostream &os,Opts::const_iterator i) const;
276 276
    void show(std::ostream &os,Groups::const_iterator i) const;
277 277
    void showHelp(Opts::const_iterator i) const;
278 278
    void showHelp(std::vector<OtherArg>::const_iterator i) const;
279 279

	
280 280
    void unknownOpt(std::string arg) const;
281 281

	
282 282
    void requiresValue(std::string arg, OptType t) const;
283 283
    void checkMandatories() const;
284 284

	
285 285
    void shortHelp() const;
286 286
    void showHelp() const;
287 287
  public:
288 288

	
289 289
    ///Start the parsing process
290 290
    ArgParser &parse();
291 291

	
292 292
    /// Synonym for parse()
293 293
    ArgParser &run()
294 294
    {
295 295
      return parse();
296 296
    }
297 297

	
298 298
    ///Give back the command name (the 0th argument)
299 299
    const std::string &commandName() const { return _command_name; }
300 300

	
301 301
    ///Check if an opion has been given to the command.
302 302
    bool given(std::string op) const
303 303
    {
304 304
      Opts::const_iterator i = _opts.find(op);
305 305
      return i!=_opts.end()?i->second.set:false;
306 306
    }
307 307

	
308 308

	
309 309
    ///Magic type for operator[]
310 310

	
311 311
    ///This is the type of the return value of ArgParser::operator[]().
312 312
    ///It automatically converts to \c int, \c double, \c bool or
313
    ///\c std::string if the type of the option matches, otherwise it
314
    ///throws an exception (i.e. it performs runtime type checking).
313
    ///\c std::string if the type of the option matches, which is checked
314
    ///with an \ref LEMON_ASSERT "assertion" (i.e. it performs runtime
315
    ///type checking).
315 316
    class RefType
316 317
    {
317 318
      const ArgParser &_parser;
318 319
      std::string _name;
319 320
    public:
320 321
      ///\e
321 322
      RefType(const ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
322 323
      ///\e
323 324
      operator bool()
324 325
      {
325 326
        Opts::const_iterator i = _parser._opts.find(_name);
326 327
        LEMON_ASSERT(i!=_parser._opts.end(),
327 328
                     std::string()+"Unkown option: '"+_name+"'");
328 329
        LEMON_ASSERT(i->second.type==ArgParser::BOOL,
329 330
                     std::string()+"'"+_name+"' is a bool option");
330 331
        return *(i->second.bool_p);
331 332
      }
332 333
      ///\e
333 334
      operator std::string()
334 335
      {
335 336
        Opts::const_iterator i = _parser._opts.find(_name);
336 337
        LEMON_ASSERT(i!=_parser._opts.end(),
337 338
                     std::string()+"Unkown option: '"+_name+"'");
338 339
        LEMON_ASSERT(i->second.type==ArgParser::STRING,
339 340
                     std::string()+"'"+_name+"' is a string option");
340 341
        return *(i->second.string_p);
341 342
      }
342 343
      ///\e
343 344
      operator double()
344 345
      {
345 346
        Opts::const_iterator i = _parser._opts.find(_name);
346 347
        LEMON_ASSERT(i!=_parser._opts.end(),
347 348
                     std::string()+"Unkown option: '"+_name+"'");
348 349
        LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
349 350
                     i->second.type==ArgParser::INTEGER,
350 351
                     std::string()+"'"+_name+"' is a floating point option");
351 352
        return i->second.type==ArgParser::DOUBLE ?
352 353
          *(i->second.double_p) : *(i->second.int_p);
353 354
      }
354 355
      ///\e
355 356
      operator int()
356 357
      {
357 358
        Opts::const_iterator i = _parser._opts.find(_name);
358 359
        LEMON_ASSERT(i!=_parser._opts.end(),
359 360
                     std::string()+"Unkown option: '"+_name+"'");
360 361
        LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
361 362
                     std::string()+"'"+_name+"' is an integer option");
362 363
        return *(i->second.int_p);
363 364
      }
364 365

	
365 366
    };
366 367

	
367 368
    ///Give back the value of an option
368 369

	
369 370
    ///Give back the value of an option.
370 371
    ///\sa RefType
371 372
    RefType operator[](const std::string &n) const
372 373
    {
373 374
      return RefType(*this, n);
374 375
    }
375 376

	
376 377
    ///Give back the non-option type arguments.
377 378

	
378 379
    ///Give back a reference to a vector consisting of the program arguments
379 380
    ///not starting with a '-' character.
380 381
    const std::vector<std::string> &files() const { return _file_args; }
381 382

	
382 383
  };
383 384
}
384 385

	
385 386
#endif // LEMON_ARG_PARSER_H
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_ASSERT_H
20 20
#define LEMON_ASSERT_H
21 21

	
22 22
/// \ingroup exceptions
23 23
/// \file
24 24
/// \brief Extended assertion handling
25 25

	
26 26
#include <lemon/error.h>
27 27

	
28 28
namespace lemon {
29 29

	
30 30
  inline void assert_fail_abort(const char *file, int line,
31 31
                                const char *function, const char* message,
32 32
                                const char *assertion)
33 33
  {
34 34
    std::cerr << file << ":" << line << ": ";
35 35
    if (function)
36 36
      std::cerr << function << ": ";
37 37
    std::cerr << message;
38 38
    if (assertion)
39 39
      std::cerr << " (assertion '" << assertion << "' failed)";
40 40
    std::cerr << std::endl;
41 41
    std::abort();
42 42
  }
43 43

	
44 44
  namespace _assert_bits {
45 45

	
46 46

	
47 47
    inline const char* cstringify(const std::string& str) {
48 48
      return str.c_str();
49 49
    }
50 50

	
51 51
    inline const char* cstringify(const char* str) {
52 52
      return str;
53 53
    }
54 54
  }
55 55
}
56 56

	
57 57
#endif // LEMON_ASSERT_H
58 58

	
59 59
#undef LEMON_ASSERT
60 60
#undef LEMON_DEBUG
61 61

	
62 62
#if (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +               \
63 63
  (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
64 64
#error "LEMON assertion system is not set properly"
65 65
#endif
66 66

	
67 67
#if ((defined(LEMON_ASSERT_ABORT) ? 1 : 0) +            \
68 68
     (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||     \
69 69
     defined(LEMON_ENABLE_ASSERTS)) &&                  \
70 70
  (defined(LEMON_DISABLE_ASSERTS) ||                    \
71 71
   defined(NDEBUG))
72 72
#error "LEMON assertion system is not set properly"
73 73
#endif
74 74

	
75 75

	
76 76
#if defined LEMON_ASSERT_ABORT
77 77
#  undef LEMON_ASSERT_HANDLER
78 78
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
79 79
#elif defined LEMON_ASSERT_CUSTOM
80 80
#  undef LEMON_ASSERT_HANDLER
81 81
#  ifndef LEMON_CUSTOM_ASSERT_HANDLER
82 82
#    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
83 83
#  endif
84 84
#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
85 85
#elif defined LEMON_DISABLE_ASSERTS
86 86
#  undef LEMON_ASSERT_HANDLER
87 87
#elif defined NDEBUG
88 88
#  undef LEMON_ASSERT_HANDLER
89 89
#else
90 90
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
91 91
#endif
92 92

	
93 93
#ifndef LEMON_FUNCTION_NAME
94 94
#  if defined __GNUC__
95 95
#    define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
96 96
#  elif defined _MSC_VER
97 97
#    define LEMON_FUNCTION_NAME (__FUNCSIG__)
98 98
#  elif __STDC_VERSION__ >= 199901L
99 99
#    define LEMON_FUNCTION_NAME (__func__)
100 100
#  else
101 101
#    define LEMON_FUNCTION_NAME ("<unknown>")
102 102
#  endif
103 103
#endif
104 104

	
105 105
#ifdef DOXYGEN
106 106

	
107 107
/// \ingroup exceptions
108 108
///
109 109
/// \brief Macro for assertion with customizable message
110 110
///
111
/// Macro for assertion with customizable message.  
111
/// Macro for assertion with customizable message.
112 112
/// \param exp An expression that must be convertible to \c bool.  If it is \c
113 113
/// false, then an assertion is raised. The concrete behaviour depends on the
114 114
/// settings of the assertion system.
115 115
/// \param msg A <tt>const char*</tt> parameter, which can be used to provide
116 116
/// information about the circumstances of the failed assertion.
117 117
///
118 118
/// The assertions are enabled in the default behaviour.
119 119
/// You can disable them with the following code:
120 120
/// \code
121 121
/// #define LEMON_DISABLE_ASSERTS
122 122
/// \endcode
123 123
/// or with compilation parameters:
124 124
/// \code
125 125
/// g++ -DLEMON_DISABLE_ASSERTS
126 126
/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
127 127
/// \endcode
128 128
/// The checking is also disabled when the standard macro \c NDEBUG is defined.
129 129
///
130 130
/// As a default behaviour the failed assertion prints a short log message to
131 131
/// the standard error and aborts the execution.
132 132
///
133 133
/// However, the following modes can be used in the assertion system:
134 134
/// - \c LEMON_ASSERT_ABORT The failed assertion prints a short log message to
135 135
///   the standard error and aborts the program. It is the default behaviour.
136 136
/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
137 137
///   function.
138 138
///   \code
139 139
///     void custom_assert_handler(const char* file, int line,
140 140
///                                const char* function, const char* message,
141 141
///                                const char* assertion);
142 142
///   \endcode
143 143
///   The name of the function should be defined as the \c
144 144
///   LEMON_CUSTOM_ASSERT_HANDLER macro name.
145 145
///   \code
146 146
///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
147 147
///   \endcode
148 148
///   Whenever an assertion is occured, the custom assertion
149 149
///   handler is called with appropiate parameters.
150 150
///
151 151
/// The assertion mode can also be changed within one compilation unit.
152 152
/// If the macros are redefined with other settings and the
153 153
/// \ref lemon/assert.h "assert.h" file is reincluded, then the
154 154
/// behaviour is changed appropiately to the new settings.
155 155
#  define LEMON_ASSERT(exp, msg)                                        \
156 156
  (static_cast<void> (!!(exp) ? 0 : (                                   \
157 157
    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
158 158
                         LEMON_FUNCTION_NAME,                           \
159 159
                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
160 160

	
161 161
/// \ingroup exceptions
162 162
///
163 163
/// \brief Macro for internal assertions
164 164
///
165 165
/// Macro for internal assertions, it is used in the library to check
166 166
/// the consistency of results of algorithms, several pre- and
167 167
/// postconditions and invariants. The checking is disabled by
168 168
/// default, but it can be turned on with the macro \c
169 169
/// LEMON_ENABLE_DEBUG.
170 170
/// \code
171 171
/// #define LEMON_ENABLE_DEBUG
172 172
/// \endcode
173 173
/// or with compilation parameters:
174 174
/// \code
175 175
/// g++ -DLEMON_ENABLE_DEBUG
176 176
/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
177 177
/// \endcode
178 178
///
179 179
/// This macro works like the \c LEMON_ASSERT macro, therefore the
180 180
/// current behaviour depends on the settings of \c LEMON_ASSERT
181 181
/// macro.
182 182
///
183 183
/// \see LEMON_ASSERT
184 184
#  define LEMON_DEBUG(exp, msg)                                         \
185 185
  (static_cast<void> (!!(exp) ? 0 : (                                   \
186 186
    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
187 187
                         LEMON_FUNCTION_NAME,                           \
188 188
                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
189 189

	
190 190
#else
191 191

	
192 192
#  ifndef LEMON_ASSERT_HANDLER
193 193
#    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
194 194
#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
195 195
#  else
196 196
#    define LEMON_ASSERT(exp, msg)                                      \
197 197
       (static_cast<void> (!!(exp) ? 0 : (                              \
198 198
        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
199 199
                             LEMON_FUNCTION_NAME,                       \
200 200
                             ::lemon::_assert_bits::cstringify(msg),    \
201 201
                             #exp), 0)))
202 202
#    if LEMON_ENABLE_DEBUG
203 203
#      define LEMON_DEBUG(exp, msg)                                     \
204 204
         (static_cast<void> (!!(exp) ? 0 : (                            \
205 205
           LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                     \
206 206
                                LEMON_FUNCTION_NAME,                    \
207 207
                                ::lemon::_assert_bits::cstringify(msg), \
208 208
                                #exp), 0)))
209 209
#    else
210 210
#      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
211 211
#    endif
212 212
#  endif
213 213

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

	
19 19
#ifndef LEMON_BFS_H
20 20
#define LEMON_BFS_H
21 21

	
22 22
///\ingroup search
23 23
///\file
24 24
///\brief BFS 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 30
#include <lemon/maps.h>
31 31
#include <lemon/path.h>
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  ///Default traits class of Bfs class.
36 36

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

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

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

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

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

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

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

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

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

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

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

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

	
112 112
  ///%BFS algorithm class.
113 113

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

	
140
    ///This error represents problems in the initialization of the
141
    ///parameters of the algorithm.
142
    class UninitializedParameter : public lemon::UninitializedParameter {
143
    public:
144
      virtual const char* what() const throw() {
145
        return "lemon::Bfs::UninitializedParameter";
146
      }
147
    };
148 138

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

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

	
164 154
    ///The traits class.
165 155
    typedef TR Traits;
166 156

	
167 157
  private:
168 158

	
169 159
    typedef typename Digraph::Node Node;
170 160
    typedef typename Digraph::NodeIt NodeIt;
171 161
    typedef typename Digraph::Arc Arc;
172 162
    typedef typename Digraph::OutArcIt OutArcIt;
173 163

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

	
193 183
    std::vector<typename Digraph::Node> _queue;
194 184
    int _queue_head,_queue_tail,_queue_next_dist;
195 185
    int _curr_dist;
196 186

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

	
218 208
  protected:
219 209

	
220 210
    Bfs() {}
221 211

	
222 212
  public:
223 213

	
224 214
    typedef Bfs Create;
225 215

	
226 216
    ///\name Named template parameters
227 217

	
228 218
    ///@{
229 219

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

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

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

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

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

	
320 315
    ///@}
321 316

	
322 317
  public:
323 318

	
324 319
    ///Constructor.
325 320

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

	
336 331
    ///Destructor.
337 332
    ~Bfs()
338 333
    {
339 334
      if(local_pred) delete _pred;
340 335
      if(local_dist) delete _dist;
341 336
      if(local_reached) delete _reached;
342 337
      if(local_processed) delete _processed;
343 338
    }
344 339

	
345 340
    ///Sets the map that stores the predecessor arcs.
346 341

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

	
362 357
    ///Sets the map that indicates which nodes are reached.
363 358

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

	
379 374
    ///Sets the map that indicates which nodes are processed.
380 375

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

	
396 391
    ///Sets the map that stores the distances of the nodes.
397 392

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

	
414 409
  public:
415 410

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

	
426 421
    ///@{
427 422

	
428 423
    ///Initializes the internal data structures.
429 424

	
430 425
    ///Initializes the internal data structures.
431 426
    ///
432 427
    void init()
433 428
    {
434 429
      create_maps();
435 430
      _queue.resize(countNodes(*G));
436 431
      _queue_head=_queue_tail=0;
437 432
      _curr_dist=1;
438 433
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
439 434
        _pred->set(u,INVALID);
440 435
        _reached->set(u,false);
441 436
        _processed->set(u,false);
442 437
      }
443 438
    }
444 439

	
445 440
    ///Adds a new source node.
446 441

	
447 442
    ///Adds a new source node to the set of nodes to be processed.
448 443
    ///
449 444
    void addSource(Node s)
450 445
    {
451 446
      if(!(*_reached)[s])
452 447
        {
453 448
          _reached->set(s,true);
454 449
          _pred->set(s,INVALID);
455 450
          _dist->set(s,0);
456 451
          _queue[_queue_head++]=s;
457 452
          _queue_next_dist=_queue_head;
458 453
        }
459 454
    }
460 455

	
461 456
    ///Processes the next node.
462 457

	
463 458
    ///Processes the next node.
464 459
    ///
465 460
    ///\return The processed node.
466 461
    ///
467 462
    ///\pre The queue must not be empty.
468 463
    Node processNextNode()
469 464
    {
470 465
      if(_queue_tail==_queue_next_dist) {
471 466
        _curr_dist++;
472 467
        _queue_next_dist=_queue_head;
473 468
      }
474 469
      Node n=_queue[_queue_tail++];
475 470
      _processed->set(n,true);
476 471
      Node m;
477 472
      for(OutArcIt e(*G,n);e!=INVALID;++e)
478 473
        if(!(*_reached)[m=G->target(e)]) {
479 474
          _queue[_queue_head++]=m;
480 475
          _reached->set(m,true);
481 476
          _pred->set(m,e);
482 477
          _dist->set(m,_curr_dist);
483 478
        }
484 479
      return n;
485 480
    }
486 481

	
487 482
    ///Processes the next node.
488 483

	
489 484
    ///Processes the next node and checks if the given target node
490 485
    ///is reached. If the target node is reachable from the processed
491 486
    ///node, then the \c reach parameter will be set to \c true.
492 487
    ///
493 488
    ///\param target The target node.
494 489
    ///\retval reach Indicates if the target node is reached.
495 490
    ///It should be initially \c false.
496 491
    ///
497 492
    ///\return The processed node.
498 493
    ///
... ...
@@ -851,734 +846,722 @@
851 846
    }
852 847

	
853 848
    ///The type of the map that indicates which nodes are processed.
854 849

	
855 850
    ///The type of the map that indicates which nodes are processed.
856 851
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
857 852
    ///By default it is a NullMap.
858 853
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
859 854
    ///Instantiates a \ref ProcessedMap.
860 855

	
861 856
    ///This function instantiates a \ref ProcessedMap.
862 857
    ///\param g is the digraph, to which
863 858
    ///we would like to define the \ref ProcessedMap.
864 859
#ifdef DOXYGEN
865 860
    static ProcessedMap *createProcessedMap(const Digraph &g)
866 861
#else
867 862
    static ProcessedMap *createProcessedMap(const Digraph &)
868 863
#endif
869 864
    {
870 865
      return new ProcessedMap();
871 866
    }
872 867

	
873 868
    ///The type of the map that indicates which nodes are reached.
874 869

	
875 870
    ///The type of the map that indicates which nodes are reached.
876 871
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
877 872
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
878 873
    ///Instantiates a \ref ReachedMap.
879 874

	
880 875
    ///This function instantiates a \ref ReachedMap.
881 876
    ///\param g is the digraph, to which
882 877
    ///we would like to define the \ref ReachedMap.
883 878
    static ReachedMap *createReachedMap(const Digraph &g)
884 879
    {
885 880
      return new ReachedMap(g);
886 881
    }
887 882

	
888 883
    ///The type of the map that stores the distances of the nodes.
889 884

	
890 885
    ///The type of the map that stores the distances of the nodes.
891 886
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
892 887
    typedef typename Digraph::template NodeMap<int> DistMap;
893 888
    ///Instantiates a \ref DistMap.
894 889

	
895 890
    ///This function instantiates a \ref DistMap.
896 891
    ///\param g is the digraph, to which we would like to define
897 892
    ///the \ref DistMap
898 893
    static DistMap *createDistMap(const Digraph &g)
899 894
    {
900 895
      return new DistMap(g);
901 896
    }
902 897

	
903 898
    ///The type of the shortest paths.
904 899

	
905 900
    ///The type of the shortest paths.
906 901
    ///It must meet the \ref concepts::Path "Path" concept.
907 902
    typedef lemon::Path<Digraph> Path;
908 903
  };
909 904

	
910 905
  /// Default traits class used by \ref BfsWizard
911 906

	
912 907
  /// To make it easier to use Bfs algorithm
913 908
  /// we have created a wizard class.
914 909
  /// This \ref BfsWizard class needs default traits,
915 910
  /// as well as the \ref Bfs class.
916 911
  /// The \ref BfsWizardBase is a class to be the default traits of the
917 912
  /// \ref BfsWizard class.
918 913
  template<class GR>
919 914
  class BfsWizardBase : public BfsWizardDefaultTraits<GR>
920 915
  {
921 916

	
922 917
    typedef BfsWizardDefaultTraits<GR> Base;
923 918
  protected:
924 919
    //The type of the nodes in the digraph.
925 920
    typedef typename Base::Digraph::Node Node;
926 921

	
927 922
    //Pointer to the digraph the algorithm runs on.
928 923
    void *_g;
929 924
    //Pointer to the map of reached nodes.
930 925
    void *_reached;
931 926
    //Pointer to the map of processed nodes.
932 927
    void *_processed;
933 928
    //Pointer to the map of predecessors arcs.
934 929
    void *_pred;
935 930
    //Pointer to the map of distances.
936 931
    void *_dist;
937 932
    //Pointer to the shortest path to the target node.
938 933
    void *_path;
939 934
    //Pointer to the distance of the target node.
940 935
    int *_di;
941 936

	
942 937
    public:
943 938
    /// Constructor.
944 939

	
945 940
    /// This constructor does not require parameters, therefore it initiates
946 941
    /// all of the attributes to \c 0.
947 942
    BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
948 943
                      _dist(0), _path(0), _di(0) {}
949 944

	
950 945
    /// Constructor.
951 946

	
952 947
    /// This constructor requires one parameter,
953 948
    /// others are initiated to \c 0.
954 949
    /// \param g The digraph the algorithm runs on.
955 950
    BfsWizardBase(const GR &g) :
956 951
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
957 952
      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
958 953

	
959 954
  };
960 955

	
961 956
  /// Auxiliary class for the function-type interface of BFS algorithm.
962 957

	
963 958
  /// This auxiliary class is created to implement the
964 959
  /// \ref bfs() "function-type interface" of \ref Bfs algorithm.
965 960
  /// It does not have own \ref run() method, it uses the functions
966 961
  /// and features of the plain \ref Bfs.
967 962
  ///
968 963
  /// This class should only be used through the \ref bfs() function,
969 964
  /// which makes it easier to use the algorithm.
970 965
  template<class TR>
971 966
  class BfsWizard : public TR
972 967
  {
973 968
    typedef TR Base;
974 969

	
975 970
    ///The type of the digraph the algorithm runs on.
976 971
    typedef typename TR::Digraph Digraph;
977 972

	
978 973
    typedef typename Digraph::Node Node;
979 974
    typedef typename Digraph::NodeIt NodeIt;
980 975
    typedef typename Digraph::Arc Arc;
981 976
    typedef typename Digraph::OutArcIt OutArcIt;
982 977

	
983 978
    ///\brief The type of the map that stores the predecessor
984 979
    ///arcs of the shortest paths.
985 980
    typedef typename TR::PredMap PredMap;
986 981
    ///\brief The type of the map that stores the distances of the nodes.
987 982
    typedef typename TR::DistMap DistMap;
988 983
    ///\brief The type of the map that indicates which nodes are reached.
989 984
    typedef typename TR::ReachedMap ReachedMap;
990 985
    ///\brief The type of the map that indicates which nodes are processed.
991 986
    typedef typename TR::ProcessedMap ProcessedMap;
992 987
    ///The type of the shortest paths
993 988
    typedef typename TR::Path Path;
994 989

	
995 990
  public:
996 991

	
997 992
    /// Constructor.
998 993
    BfsWizard() : TR() {}
999 994

	
1000 995
    /// Constructor that requires parameters.
1001 996

	
1002 997
    /// Constructor that requires parameters.
1003 998
    /// These parameters will be the default values for the traits class.
1004 999
    /// \param g The digraph the algorithm runs on.
1005 1000
    BfsWizard(const Digraph &g) :
1006 1001
      TR(g) {}
1007 1002

	
1008 1003
    ///Copy constructor
1009 1004
    BfsWizard(const TR &b) : TR(b) {}
1010 1005

	
1011 1006
    ~BfsWizard() {}
1012 1007

	
1013 1008
    ///Runs BFS algorithm from the given source node.
1014 1009

	
1015 1010
    ///This method runs BFS algorithm from node \c s
1016 1011
    ///in order to compute the shortest path to each node.
1017 1012
    void run(Node s)
1018 1013
    {
1019 1014
      Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
1020 1015
      if (Base::_pred)
1021 1016
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1022 1017
      if (Base::_dist)
1023 1018
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1024 1019
      if (Base::_reached)
1025 1020
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
1026 1021
      if (Base::_processed)
1027 1022
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1028 1023
      if (s!=INVALID)
1029 1024
        alg.run(s);
1030 1025
      else
1031 1026
        alg.run();
1032 1027
    }
1033 1028

	
1034 1029
    ///Finds the shortest path between \c s and \c t.
1035 1030

	
1036 1031
    ///This method runs BFS algorithm from node \c s
1037 1032
    ///in order to compute the shortest path to node \c t
1038 1033
    ///(it stops searching when \c t is processed).
1039 1034
    ///
1040 1035
    ///\return \c true if \c t is reachable form \c s.
1041 1036
    bool run(Node s, Node t)
1042 1037
    {
1043
      if (s==INVALID || t==INVALID) throw UninitializedParameter();
1044 1038
      Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
1045 1039
      if (Base::_pred)
1046 1040
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1047 1041
      if (Base::_dist)
1048 1042
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1049 1043
      if (Base::_reached)
1050 1044
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
1051 1045
      if (Base::_processed)
1052 1046
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1053 1047
      alg.run(s,t);
1054 1048
      if (Base::_path)
1055 1049
        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
1056 1050
      if (Base::_di)
1057 1051
        *Base::_di = alg.dist(t);
1058 1052
      return alg.reached(t);
1059 1053
    }
1060 1054

	
1061 1055
    ///Runs BFS algorithm to visit all nodes in the digraph.
1062 1056

	
1063 1057
    ///This method runs BFS algorithm in order to compute
1064 1058
    ///the shortest path to each node.
1065 1059
    void run()
1066 1060
    {
1067 1061
      run(INVALID);
1068 1062
    }
1069 1063

	
1070 1064
    template<class T>
1071 1065
    struct SetPredMapBase : public Base {
1072 1066
      typedef T PredMap;
1073 1067
      static PredMap *createPredMap(const Digraph &) { return 0; };
1074 1068
      SetPredMapBase(const TR &b) : TR(b) {}
1075 1069
    };
1076 1070
    ///\brief \ref named-func-param "Named parameter"
1077 1071
    ///for setting \ref PredMap object.
1078 1072
    ///
1079 1073
    ///\ref named-func-param "Named parameter"
1080 1074
    ///for setting \ref PredMap object.
1081 1075
    template<class T>
1082 1076
    BfsWizard<SetPredMapBase<T> > predMap(const T &t)
1083 1077
    {
1084 1078
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1085 1079
      return BfsWizard<SetPredMapBase<T> >(*this);
1086 1080
    }
1087 1081

	
1088 1082
    template<class T>
1089 1083
    struct SetReachedMapBase : public Base {
1090 1084
      typedef T ReachedMap;
1091 1085
      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
1092 1086
      SetReachedMapBase(const TR &b) : TR(b) {}
1093 1087
    };
1094 1088
    ///\brief \ref named-func-param "Named parameter"
1095 1089
    ///for setting \ref ReachedMap object.
1096 1090
    ///
1097 1091
    /// \ref named-func-param "Named parameter"
1098 1092
    ///for setting \ref ReachedMap object.
1099 1093
    template<class T>
1100 1094
    BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
1101 1095
    {
1102 1096
      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
1103 1097
      return BfsWizard<SetReachedMapBase<T> >(*this);
1104 1098
    }
1105 1099

	
1106 1100
    template<class T>
1107 1101
    struct SetDistMapBase : public Base {
1108 1102
      typedef T DistMap;
1109 1103
      static DistMap *createDistMap(const Digraph &) { return 0; };
1110 1104
      SetDistMapBase(const TR &b) : TR(b) {}
1111 1105
    };
1112 1106
    ///\brief \ref named-func-param "Named parameter"
1113 1107
    ///for setting \ref DistMap object.
1114 1108
    ///
1115 1109
    /// \ref named-func-param "Named parameter"
1116 1110
    ///for setting \ref DistMap object.
1117 1111
    template<class T>
1118 1112
    BfsWizard<SetDistMapBase<T> > distMap(const T &t)
1119 1113
    {
1120 1114
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1121 1115
      return BfsWizard<SetDistMapBase<T> >(*this);
1122 1116
    }
1123 1117

	
1124 1118
    template<class T>
1125 1119
    struct SetProcessedMapBase : public Base {
1126 1120
      typedef T ProcessedMap;
1127 1121
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1128 1122
      SetProcessedMapBase(const TR &b) : TR(b) {}
1129 1123
    };
1130 1124
    ///\brief \ref named-func-param "Named parameter"
1131 1125
    ///for setting \ref ProcessedMap object.
1132 1126
    ///
1133 1127
    /// \ref named-func-param "Named parameter"
1134 1128
    ///for setting \ref ProcessedMap object.
1135 1129
    template<class T>
1136 1130
    BfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
1137 1131
    {
1138 1132
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1139 1133
      return BfsWizard<SetProcessedMapBase<T> >(*this);
1140 1134
    }
1141 1135

	
1142 1136
    template<class T>
1143 1137
    struct SetPathBase : public Base {
1144 1138
      typedef T Path;
1145 1139
      SetPathBase(const TR &b) : TR(b) {}
1146 1140
    };
1147 1141
    ///\brief \ref named-func-param "Named parameter"
1148 1142
    ///for getting the shortest path to the target node.
1149 1143
    ///
1150 1144
    ///\ref named-func-param "Named parameter"
1151 1145
    ///for getting the shortest path to the target node.
1152 1146
    template<class T>
1153 1147
    BfsWizard<SetPathBase<T> > path(const T &t)
1154 1148
    {
1155 1149
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1156 1150
      return BfsWizard<SetPathBase<T> >(*this);
1157 1151
    }
1158 1152

	
1159 1153
    ///\brief \ref named-func-param "Named parameter"
1160 1154
    ///for getting the distance of the target node.
1161 1155
    ///
1162 1156
    ///\ref named-func-param "Named parameter"
1163 1157
    ///for getting the distance of the target node.
1164 1158
    BfsWizard dist(const int &d)
1165 1159
    {
1166 1160
      Base::_di=const_cast<int*>(&d);
1167 1161
      return *this;
1168 1162
    }
1169 1163

	
1170 1164
  };
1171 1165

	
1172 1166
  ///Function-type interface for BFS algorithm.
1173 1167

	
1174 1168
  /// \ingroup search
1175 1169
  ///Function-type interface for BFS algorithm.
1176 1170
  ///
1177 1171
  ///This function also has several \ref named-func-param "named parameters",
1178 1172
  ///they are declared as the members of class \ref BfsWizard.
1179 1173
  ///The following examples show how to use these parameters.
1180 1174
  ///\code
1181 1175
  ///  // Compute shortest path from node s to each node
1182 1176
  ///  bfs(g).predMap(preds).distMap(dists).run(s);
1183 1177
  ///
1184 1178
  ///  // Compute shortest path from s to t
1185 1179
  ///  bool reached = bfs(g).path(p).dist(d).run(s,t);
1186 1180
  ///\endcode
1187 1181
  ///\warning Don't forget to put the \ref BfsWizard::run() "run()"
1188 1182
  ///to the end of the parameter list.
1189 1183
  ///\sa BfsWizard
1190 1184
  ///\sa Bfs
1191 1185
  template<class GR>
1192 1186
  BfsWizard<BfsWizardBase<GR> >
1193 1187
  bfs(const GR &digraph)
1194 1188
  {
1195 1189
    return BfsWizard<BfsWizardBase<GR> >(digraph);
1196 1190
  }
1197 1191

	
1198 1192
#ifdef DOXYGEN
1199 1193
  /// \brief Visitor class for BFS.
1200 1194
  ///
1201 1195
  /// This class defines the interface of the BfsVisit events, and
1202 1196
  /// it could be the base of a real visitor class.
1203 1197
  template <typename _Digraph>
1204 1198
  struct BfsVisitor {
1205 1199
    typedef _Digraph Digraph;
1206 1200
    typedef typename Digraph::Arc Arc;
1207 1201
    typedef typename Digraph::Node Node;
1208 1202
    /// \brief Called for the source node(s) of the BFS.
1209 1203
    ///
1210 1204
    /// This function is called for the source node(s) of the BFS.
1211 1205
    void start(const Node& node) {}
1212 1206
    /// \brief Called when a node is reached first time.
1213 1207
    ///
1214 1208
    /// This function is called when a node is reached first time.
1215 1209
    void reach(const Node& node) {}
1216 1210
    /// \brief Called when a node is processed.
1217 1211
    ///
1218 1212
    /// This function is called when a node is processed.
1219 1213
    void process(const Node& node) {}
1220 1214
    /// \brief Called when an arc reaches a new node.
1221 1215
    ///
1222 1216
    /// This function is called when the BFS finds an arc whose target node
1223 1217
    /// is not reached yet.
1224 1218
    void discover(const Arc& arc) {}
1225 1219
    /// \brief Called when an arc is examined but its target node is
1226 1220
    /// already discovered.
1227 1221
    ///
1228 1222
    /// This function is called when an arc is examined but its target node is
1229 1223
    /// already discovered.
1230 1224
    void examine(const Arc& arc) {}
1231 1225
  };
1232 1226
#else
1233 1227
  template <typename _Digraph>
1234 1228
  struct BfsVisitor {
1235 1229
    typedef _Digraph Digraph;
1236 1230
    typedef typename Digraph::Arc Arc;
1237 1231
    typedef typename Digraph::Node Node;
1238 1232
    void start(const Node&) {}
1239 1233
    void reach(const Node&) {}
1240 1234
    void process(const Node&) {}
1241 1235
    void discover(const Arc&) {}
1242 1236
    void examine(const Arc&) {}
1243 1237

	
1244 1238
    template <typename _Visitor>
1245 1239
    struct Constraints {
1246 1240
      void constraints() {
1247 1241
        Arc arc;
1248 1242
        Node node;
1249 1243
        visitor.start(node);
1250 1244
        visitor.reach(node);
1251 1245
        visitor.process(node);
1252 1246
        visitor.discover(arc);
1253 1247
        visitor.examine(arc);
1254 1248
      }
1255 1249
      _Visitor& visitor;
1256 1250
    };
1257 1251
  };
1258 1252
#endif
1259 1253

	
1260 1254
  /// \brief Default traits class of BfsVisit class.
1261 1255
  ///
1262 1256
  /// Default traits class of BfsVisit class.
1263 1257
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1264 1258
  template<class _Digraph>
1265 1259
  struct BfsVisitDefaultTraits {
1266 1260

	
1267 1261
    /// \brief The type of the digraph the algorithm runs on.
1268 1262
    typedef _Digraph Digraph;
1269 1263

	
1270 1264
    /// \brief The type of the map that indicates which nodes are reached.
1271 1265
    ///
1272 1266
    /// The type of the map that indicates which nodes are reached.
1273 1267
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1274 1268
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
1275 1269

	
1276 1270
    /// \brief Instantiates a \ref ReachedMap.
1277 1271
    ///
1278 1272
    /// This function instantiates a \ref ReachedMap.
1279 1273
    /// \param digraph is the digraph, to which
1280 1274
    /// we would like to define the \ref ReachedMap.
1281 1275
    static ReachedMap *createReachedMap(const Digraph &digraph) {
1282 1276
      return new ReachedMap(digraph);
1283 1277
    }
1284 1278

	
1285 1279
  };
1286 1280

	
1287 1281
  /// \ingroup search
1288 1282
  ///
1289 1283
  /// \brief %BFS algorithm class with visitor interface.
1290 1284
  ///
1291 1285
  /// This class provides an efficient implementation of the %BFS algorithm
1292 1286
  /// with visitor interface.
1293 1287
  ///
1294 1288
  /// The %BfsVisit class provides an alternative interface to the Bfs
1295 1289
  /// class. It works with callback mechanism, the BfsVisit object calls
1296 1290
  /// the member functions of the \c Visitor class on every BFS event.
1297 1291
  ///
1298 1292
  /// This interface of the BFS algorithm should be used in special cases
1299 1293
  /// when extra actions have to be performed in connection with certain
1300 1294
  /// events of the BFS algorithm. Otherwise consider to use Bfs or bfs()
1301 1295
  /// instead.
1302 1296
  ///
1303 1297
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1304 1298
  /// The default value is
1305 1299
  /// \ref ListDigraph. The value of _Digraph is not used directly by
1306 1300
  /// \ref BfsVisit, it is only passed to \ref BfsVisitDefaultTraits.
1307 1301
  /// \tparam _Visitor The Visitor type that is used by the algorithm.
1308 1302
  /// \ref BfsVisitor "BfsVisitor<_Digraph>" is an empty visitor, which
1309 1303
  /// does not observe the BFS events. If you want to observe the BFS
1310 1304
  /// events, you should implement your own visitor class.
1311 1305
  /// \tparam _Traits Traits class to set various data types used by the
1312 1306
  /// algorithm. The default traits class is
1313 1307
  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<_Digraph>".
1314 1308
  /// See \ref BfsVisitDefaultTraits for the documentation of
1315 1309
  /// a BFS visit traits class.
1316 1310
#ifdef DOXYGEN
1317 1311
  template <typename _Digraph, typename _Visitor, typename _Traits>
1318 1312
#else
1319 1313
  template <typename _Digraph = ListDigraph,
1320 1314
            typename _Visitor = BfsVisitor<_Digraph>,
1321 1315
            typename _Traits = BfsDefaultTraits<_Digraph> >
1322 1316
#endif
1323 1317
  class BfsVisit {
1324 1318
  public:
1325 1319

	
1326
    /// \brief \ref Exception for uninitialized parameters.
1327
    ///
1328
    /// This error represents problems in the initialization
1329
    /// of the parameters of the algorithm.
1330
    class UninitializedParameter : public lemon::UninitializedParameter {
1331
    public:
1332
      virtual const char* what() const throw()
1333
      {
1334
        return "lemon::BfsVisit::UninitializedParameter";
1335
      }
1336
    };
1337

	
1338 1320
    ///The traits class.
1339 1321
    typedef _Traits Traits;
1340 1322

	
1341 1323
    ///The type of the digraph the algorithm runs on.
1342 1324
    typedef typename Traits::Digraph Digraph;
1343 1325

	
1344 1326
    ///The visitor type used by the algorithm.
1345 1327
    typedef _Visitor Visitor;
1346 1328

	
1347 1329
    ///The type of the map that indicates which nodes are reached.
1348 1330
    typedef typename Traits::ReachedMap ReachedMap;
1349 1331

	
1350 1332
  private:
1351 1333

	
1352 1334
    typedef typename Digraph::Node Node;
1353 1335
    typedef typename Digraph::NodeIt NodeIt;
1354 1336
    typedef typename Digraph::Arc Arc;
1355 1337
    typedef typename Digraph::OutArcIt OutArcIt;
1356 1338

	
1357 1339
    //Pointer to the underlying digraph.
1358 1340
    const Digraph *_digraph;
1359 1341
    //Pointer to the visitor object.
1360 1342
    Visitor *_visitor;
1361 1343
    //Pointer to the map of reached status of the nodes.
1362 1344
    ReachedMap *_reached;
1363 1345
    //Indicates if _reached is locally allocated (true) or not.
1364 1346
    bool local_reached;
1365 1347

	
1366 1348
    std::vector<typename Digraph::Node> _list;
1367 1349
    int _list_front, _list_back;
1368 1350

	
1369 1351
    //Creates the maps if necessary.
1370 1352
    void create_maps() {
1371 1353
      if(!_reached) {
1372 1354
        local_reached = true;
1373 1355
        _reached = Traits::createReachedMap(*_digraph);
1374 1356
      }
1375 1357
    }
1376 1358

	
1377 1359
  protected:
1378 1360

	
1379 1361
    BfsVisit() {}
1380 1362

	
1381 1363
  public:
1382 1364

	
1383 1365
    typedef BfsVisit Create;
1384 1366

	
1385 1367
    /// \name Named template parameters
1386 1368

	
1387 1369
    ///@{
1388 1370
    template <class T>
1389 1371
    struct SetReachedMapTraits : public Traits {
1390 1372
      typedef T ReachedMap;
1391 1373
      static ReachedMap *createReachedMap(const Digraph &digraph) {
1392
        throw UninitializedParameter();
1374
        LEMON_ASSERT(false, "ReachedMap is not initialized");
1375
        return 0; // ignore warnings
1393 1376
      }
1394 1377
    };
1395 1378
    /// \brief \ref named-templ-param "Named parameter" for setting
1396 1379
    /// ReachedMap type.
1397 1380
    ///
1398 1381
    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
1399 1382
    template <class T>
1400 1383
    struct SetReachedMap : public BfsVisit< Digraph, Visitor,
1401 1384
                                            SetReachedMapTraits<T> > {
1402 1385
      typedef BfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
1403 1386
    };
1404 1387
    ///@}
1405 1388

	
1406 1389
  public:
1407 1390

	
1408 1391
    /// \brief Constructor.
1409 1392
    ///
1410 1393
    /// Constructor.
1411 1394
    ///
1412 1395
    /// \param digraph The digraph the algorithm runs on.
1413 1396
    /// \param visitor The visitor object of the algorithm.
1414 1397
    BfsVisit(const Digraph& digraph, Visitor& visitor)
1415 1398
      : _digraph(&digraph), _visitor(&visitor),
1416 1399
        _reached(0), local_reached(false) {}
1417 1400

	
1418 1401
    /// \brief Destructor.
1419 1402
    ~BfsVisit() {
1420 1403
      if(local_reached) delete _reached;
1421 1404
    }
1422 1405

	
1423 1406
    /// \brief Sets the map that indicates which nodes are reached.
1424 1407
    ///
1425 1408
    /// Sets the map that indicates which nodes are reached.
1426 1409
    /// If you don't use this function before calling \ref run(),
1427 1410
    /// it will allocate one. The destructor deallocates this
1428 1411
    /// automatically allocated map, of course.
1429 1412
    /// \return <tt> (*this) </tt>
1430 1413
    BfsVisit &reachedMap(ReachedMap &m) {
1431 1414
      if(local_reached) {
1432 1415
        delete _reached;
1433 1416
        local_reached = false;
1434 1417
      }
1435 1418
      _reached = &m;
1436 1419
      return *this;
1437 1420
    }
1438 1421

	
1439 1422
  public:
1440 1423

	
1441 1424
    /// \name Execution control
1442 1425
    /// The simplest way to execute the algorithm is to use
1443 1426
    /// one of the member functions called \ref lemon::BfsVisit::run()
1444 1427
    /// "run()".
1445 1428
    /// \n
1446 1429
    /// If you need more control on the execution, first you must call
1447 1430
    /// \ref lemon::BfsVisit::init() "init()", then you can add several
1448 1431
    /// source nodes with \ref lemon::BfsVisit::addSource() "addSource()".
1449 1432
    /// Finally \ref lemon::BfsVisit::start() "start()" will perform the
1450 1433
    /// actual path computation.
1451 1434

	
1452 1435
    /// @{
1453 1436

	
1454 1437
    /// \brief Initializes the internal data structures.
1455 1438
    ///
1456 1439
    /// Initializes the internal data structures.
1457 1440
    void init() {
1458 1441
      create_maps();
1459 1442
      _list.resize(countNodes(*_digraph));
1460 1443
      _list_front = _list_back = -1;
1461 1444
      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
1462 1445
        _reached->set(u, false);
1463 1446
      }
1464 1447
    }
1465 1448

	
1466 1449
    /// \brief Adds a new source node.
1467 1450
    ///
1468 1451
    /// Adds a new source node to the set of nodes to be processed.
1469 1452
    void addSource(Node s) {
1470 1453
      if(!(*_reached)[s]) {
1471 1454
          _reached->set(s,true);
1472 1455
          _visitor->start(s);
1473 1456
          _visitor->reach(s);
1474 1457
          _list[++_list_back] = s;
1475 1458
        }
1476 1459
    }
1477 1460

	
1478 1461
    /// \brief Processes the next node.
1479 1462
    ///
1480 1463
    /// Processes the next node.
1481 1464
    ///
1482 1465
    /// \return The processed node.
1483 1466
    ///
1484 1467
    /// \pre The queue must not be empty.
1485 1468
    Node processNextNode() {
1486 1469
      Node n = _list[++_list_front];
1487 1470
      _visitor->process(n);
1488 1471
      Arc e;
1489 1472
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1490 1473
        Node m = _digraph->target(e);
1491 1474
        if (!(*_reached)[m]) {
1492 1475
          _visitor->discover(e);
1493 1476
          _visitor->reach(m);
1494 1477
          _reached->set(m, true);
1495 1478
          _list[++_list_back] = m;
1496 1479
        } else {
1497 1480
          _visitor->examine(e);
1498 1481
        }
1499 1482
      }
1500 1483
      return n;
1501 1484
    }
1502 1485

	
1503 1486
    /// \brief Processes the next node.
1504 1487
    ///
1505 1488
    /// Processes the next node and checks if the given target node
1506 1489
    /// is reached. If the target node is reachable from the processed
1507 1490
    /// node, then the \c reach parameter will be set to \c true.
1508 1491
    ///
1509 1492
    /// \param target The target node.
1510 1493
    /// \retval reach Indicates if the target node is reached.
1511 1494
    /// It should be initially \c false.
1512 1495
    ///
1513 1496
    /// \return The processed node.
1514 1497
    ///
1515 1498
    /// \pre The queue must not be empty.
1516 1499
    Node processNextNode(Node target, bool& reach) {
1517 1500
      Node n = _list[++_list_front];
1518 1501
      _visitor->process(n);
1519 1502
      Arc e;
1520 1503
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1521 1504
        Node m = _digraph->target(e);
1522 1505
        if (!(*_reached)[m]) {
1523 1506
          _visitor->discover(e);
1524 1507
          _visitor->reach(m);
1525 1508
          _reached->set(m, true);
1526 1509
          _list[++_list_back] = m;
1527 1510
          reach = reach || (target == m);
1528 1511
        } else {
1529 1512
          _visitor->examine(e);
1530 1513
        }
1531 1514
      }
1532 1515
      return n;
1533 1516
    }
1534 1517

	
1535 1518
    /// \brief Processes the next node.
1536 1519
    ///
1537 1520
    /// Processes the next node and checks if at least one of reached
1538 1521
    /// nodes has \c true value in the \c nm node map. If one node
1539 1522
    /// with \c true value is reachable from the processed node, then the
1540 1523
    /// \c rnode parameter will be set to the first of such nodes.
1541 1524
    ///
1542 1525
    /// \param nm A \c bool (or convertible) node map that indicates the
1543 1526
    /// possible targets.
1544 1527
    /// \retval rnode The reached target node.
1545 1528
    /// It should be initially \c INVALID.
1546 1529
    ///
1547 1530
    /// \return The processed node.
1548 1531
    ///
1549 1532
    /// \pre The queue must not be empty.
1550 1533
    template <typename NM>
1551 1534
    Node processNextNode(const NM& nm, Node& rnode) {
1552 1535
      Node n = _list[++_list_front];
1553 1536
      _visitor->process(n);
1554 1537
      Arc e;
1555 1538
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1556 1539
        Node m = _digraph->target(e);
1557 1540
        if (!(*_reached)[m]) {
1558 1541
          _visitor->discover(e);
1559 1542
          _visitor->reach(m);
1560 1543
          _reached->set(m, true);
1561 1544
          _list[++_list_back] = m;
1562 1545
          if (nm[m] && rnode == INVALID) rnode = m;
1563 1546
        } else {
1564 1547
          _visitor->examine(e);
1565 1548
        }
1566 1549
      }
1567 1550
      return n;
1568 1551
    }
1569 1552

	
1570 1553
    /// \brief The next node to be processed.
1571 1554
    ///
1572 1555
    /// Returns the next node to be processed or \c INVALID if the queue
1573 1556
    /// is empty.
1574 1557
    Node nextNode() const {
1575 1558
      return _list_front != _list_back ? _list[_list_front + 1] : INVALID;
1576 1559
    }
1577 1560

	
1578 1561
    /// \brief Returns \c false if there are nodes
1579 1562
    /// to be processed.
1580 1563
    ///
1581 1564
    /// Returns \c false if there are nodes
1582 1565
    /// to be processed in the queue.
1583 1566
    bool emptyQueue() const { return _list_front == _list_back; }
1584 1567

	
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 concept
20 20
///\file
21 21
///\brief The concept of heaps.
22 22

	
23 23
#ifndef LEMON_CONCEPT_HEAP_H
24 24
#define LEMON_CONCEPT_HEAP_H
25 25

	
26 26
#include <lemon/core.h>
27 27

	
28 28
namespace lemon {
29 29

	
30 30
  namespace concepts {
31 31

	
32 32
    /// \addtogroup concept
33 33
    /// @{
34 34

	
35 35
    /// \brief The heap concept.
36 36
    ///
37 37
    /// Concept class describing the main interface of heaps.
38 38
    template <typename Priority, typename ItemIntMap>
39 39
    class Heap {
40 40
    public:
41 41

	
42 42
      /// Type of the items stored in the heap.
43 43
      typedef typename ItemIntMap::Key Item;
44 44

	
45 45
      /// Type of the priorities.
46 46
      typedef Priority Prio;
47 47

	
48 48
      /// \brief Type to represent the states of the items.
49 49
      ///
50 50
      /// Each item has a state associated to it. It can be "in heap",
51 51
      /// "pre heap" or "post heap". The later two are indifferent
52 52
      /// from the point of view of the heap, but may be useful for
53 53
      /// the user.
54 54
      ///
55 55
      /// The \c ItemIntMap must be initialized in such a way, that it
56 56
      /// assigns \c PRE_HEAP (<tt>-1</tt>) to every item.
57 57
      enum State {
58 58
        IN_HEAP = 0,
59 59
        PRE_HEAP = -1,
60 60
        POST_HEAP = -2
61 61
      };
62 62

	
63 63
      /// \brief The constructor.
64 64
      ///
65 65
      /// The constructor.
66 66
      /// \param map A map that assigns \c int values to keys of type
67 67
      /// \c Item. It is used internally by the heap implementations to
68 68
      /// handle the cross references. The assigned value must be
69 69
      /// \c PRE_HEAP (<tt>-1</tt>) for every item.
70 70
      explicit Heap(ItemIntMap &map) {}
71 71

	
72 72
      /// \brief The number of items stored in the heap.
73 73
      ///
74 74
      /// Returns the number of items stored in the heap.
75 75
      int size() const { return 0; }
76 76

	
77 77
      /// \brief Checks if the heap is empty.
78 78
      ///
79 79
      /// Returns \c true if the heap is empty.
80 80
      bool empty() const { return false; }
81 81

	
82 82
      /// \brief Makes the heap empty.
83 83
      ///
84 84
      /// Makes the heap empty.
85 85
      void clear();
86 86

	
87 87
      /// \brief Inserts an item into the heap with the given priority.
88 88
      ///
89 89
      /// Inserts the given item into the heap with the given priority.
90 90
      /// \param i The item to insert.
91 91
      /// \param p The priority of the item.
92 92
      void push(const Item &i, const Prio &p) {}
93 93

	
94 94
      /// \brief Returns the item having minimum priority.
95 95
      ///
96 96
      /// Returns the item having minimum priority.
97 97
      /// \pre The heap must be non-empty.
98 98
      Item top() const {}
99 99

	
100 100
      /// \brief The minimum priority.
101 101
      ///
102 102
      /// Returns the minimum priority.
103 103
      /// \pre The heap must be non-empty.
104 104
      Prio prio() const {}
105 105

	
106 106
      /// \brief Removes the item having minimum priority.
107 107
      ///
108 108
      /// Removes the item having minimum priority.
109 109
      /// \pre The heap must be non-empty.
110 110
      void pop() {}
111 111

	
112 112
      /// \brief Removes an item from the heap.
113 113
      ///
114 114
      /// Removes the given item from the heap if it is already stored.
115 115
      /// \param i The item to delete.
116 116
      void erase(const Item &i) {}
117 117

	
118 118
      /// \brief The priority of an item.
119 119
      ///
120 120
      /// Returns the priority of the given item.
121 121
      /// \pre \c i must be in the heap.
122 122
      /// \param i The item.
123 123
      Prio operator[](const Item &i) const {}
124 124

	
125 125
      /// \brief Sets the priority of an item or inserts it, if it is
126 126
      /// not stored in the heap.
127 127
      ///
128 128
      /// This method sets the priority of the given item if it is
129 129
      /// already stored in the heap.
130 130
      /// Otherwise it inserts the given item with the given priority.
131 131
      ///
132
      /// It may throw an \ref UnderflowPriorityException.
133 132
      /// \param i The item.
134 133
      /// \param p The priority.
135 134
      void set(const Item &i, const Prio &p) {}
136 135

	
137 136
      /// \brief Decreases the priority of an item to the given value.
138 137
      ///
139 138
      /// Decreases the priority of an item to the given value.
140 139
      /// \pre \c i must be stored in the heap with priority at least \c p.
141 140
      /// \param i The item.
142 141
      /// \param p The priority.
143 142
      void decrease(const Item &i, const Prio &p) {}
144 143

	
145 144
      /// \brief Increases the priority of an item to the given value.
146 145
      ///
147 146
      /// Increases the priority of an item to the given value.
148 147
      /// \pre \c i must be stored in the heap with priority at most \c p.
149 148
      /// \param i The item.
150 149
      /// \param p The priority.
151 150
      void increase(const Item &i, const Prio &p) {}
152 151

	
153 152
      /// \brief Returns if an item is in, has already been in, or has
154 153
      /// never been in the heap.
155 154
      ///
156 155
      /// This method returns \c PRE_HEAP if the given item has never
157 156
      /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
158 157
      /// and \c POST_HEAP otherwise.
159 158
      /// In the latter case it is possible that the item will get back
160 159
      /// to the heap again.
161 160
      /// \param i The item.
162 161
      State state(const Item &i) const {}
163 162

	
164 163
      /// \brief Sets the state of an item in the heap.
165 164
      ///
166 165
      /// Sets the state of the given item in the heap. It can be used
167 166
      /// to manually clear the heap when it is important to achive the
168 167
      /// better time complexity.
169 168
      /// \param i The item.
170 169
      /// \param st The state. It should not be \c IN_HEAP.
171 170
      void state(const Item& i, State st) {}
172 171

	
173 172

	
174 173
      template <typename _Heap>
175 174
      struct Constraints {
176 175
      public:
177 176
        void constraints() {
178 177
          typedef typename _Heap::Item OwnItem;
179 178
          typedef typename _Heap::Prio OwnPrio;
180 179
          typedef typename _Heap::State OwnState;
181 180

	
182 181
          Item item;
183 182
          Prio prio;
184 183
          item=Item();
185 184
          prio=Prio();
186 185
          ignore_unused_variable_warning(item);
187 186
          ignore_unused_variable_warning(prio);
188 187

	
189 188
          OwnItem own_item;
190 189
          OwnPrio own_prio;
191 190
          OwnState own_state;
192 191
          own_item=Item();
193 192
          own_prio=Prio();
194 193
          ignore_unused_variable_warning(own_item);
195 194
          ignore_unused_variable_warning(own_prio);
196 195
          ignore_unused_variable_warning(own_state);
197 196

	
198 197
          _Heap heap1(map);
199 198
          _Heap heap2 = heap1;
200 199
          ignore_unused_variable_warning(heap1);
201 200
          ignore_unused_variable_warning(heap2);
202 201

	
203 202
          int s = heap.size();
204 203
          ignore_unused_variable_warning(s);
205 204
          bool e = heap.empty();
206 205
          ignore_unused_variable_warning(e);
207 206

	
208 207
          prio = heap.prio();
209 208
          item = heap.top();
210 209
          prio = heap[item];
211 210
          own_prio = heap.prio();
212 211
          own_item = heap.top();
213 212
          own_prio = heap[own_item];
214 213

	
215 214
          heap.push(item, prio);
216 215
          heap.push(own_item, own_prio);
217 216
          heap.pop();
218 217

	
219 218
          heap.set(item, prio);
220 219
          heap.decrease(item, prio);
221 220
          heap.increase(item, prio);
222 221
          heap.set(own_item, own_prio);
223 222
          heap.decrease(own_item, own_prio);
224 223
          heap.increase(own_item, own_prio);
225 224

	
226 225
          heap.erase(item);
227 226
          heap.erase(own_item);
228 227
          heap.clear();
229 228

	
230 229
          own_state = heap.state(own_item);
231 230
          heap.state(own_item, own_state);
232 231

	
233 232
          own_state = _Heap::PRE_HEAP;
234 233
          own_state = _Heap::IN_HEAP;
235 234
          own_state = _Heap::POST_HEAP;
236 235
        }
237 236

	
238 237
        _Heap& heap;
239 238
        ItemIntMap& map;
240 239
      };
241 240
    };
242 241

	
243 242
    /// @}
244 243
  } // namespace lemon
245 244
}
246 245
#endif // LEMON_CONCEPT_PATH_H
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 30
#include <lemon/assert.h>
31 31
#include <lemon/maps.h>
32 32
#include <lemon/path.h>
33 33

	
34 34
namespace lemon {
35 35

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
141
    ///This error represents problems in the initialization of the
142
    ///parameters of the algorithm.
143
    class UninitializedParameter : public lemon::UninitializedParameter {
144
    public:
145
      virtual const char* what() const throw() {
146
        return "lemon::Dfs::UninitializedParameter";
147
      }
148
    };
149 139

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

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

	
165 155
    ///The traits class.
166 156
    typedef TR Traits;
167 157

	
168 158
  private:
169 159

	
170 160
    typedef typename Digraph::Node Node;
171 161
    typedef typename Digraph::NodeIt NodeIt;
172 162
    typedef typename Digraph::Arc Arc;
173 163
    typedef typename Digraph::OutArcIt OutArcIt;
174 164

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

	
194 184
    std::vector<typename Digraph::OutArcIt> _stack;
195 185
    int _stack_head;
196 186

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

	
218 208
  protected:
219 209

	
220 210
    Dfs() {}
221 211

	
222 212
  public:
223 213

	
224 214
    typedef Dfs Create;
225 215

	
226 216
    ///\name Named template parameters
227 217

	
228 218
    ///@{
229 219

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

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

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

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

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

	
320 314
    ///@}
321 315

	
322 316
  public:
323 317

	
324 318
    ///Constructor.
325 319

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

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

	
345 339
    ///Sets the map that stores the predecessor arcs.
346 340

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

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

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

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

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

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

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

	
414 408
  public:
415 409

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

	
426 420
    ///@{
427 421

	
428 422
    ///Initializes the internal data structures.
429 423

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

	
444 438
    ///Adds a new source node.
445 439

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

	
472 466
    ///Processes the next arc.
473 467

	
474 468
    ///Processes the next arc.
475 469
    ///
476 470
    ///\return The processed arc.
477 471
    ///
478 472
    ///\pre The stack must not be empty.
479 473
    Arc processNextArc()
480 474
    {
481 475
      Node m;
... ...
@@ -785,747 +779,735 @@
785 779
    }
786 780

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

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

	
795 789
    ///This function instantiates a \ref ProcessedMap.
796 790
    ///\param g is the digraph, to which
797 791
    ///we would like to define the \ref ProcessedMap.
798 792
#ifdef DOXYGEN
799 793
    static ProcessedMap *createProcessedMap(const Digraph &g)
800 794
#else
801 795
    static ProcessedMap *createProcessedMap(const Digraph &)
802 796
#endif
803 797
    {
804 798
      return new ProcessedMap();
805 799
    }
806 800

	
807 801
    ///The type of the map that indicates which nodes are reached.
808 802

	
809 803
    ///The type of the map that indicates which nodes are reached.
810 804
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
811 805
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
812 806
    ///Instantiates a \ref ReachedMap.
813 807

	
814 808
    ///This function instantiates a \ref ReachedMap.
815 809
    ///\param g is the digraph, to which
816 810
    ///we would like to define the \ref ReachedMap.
817 811
    static ReachedMap *createReachedMap(const Digraph &g)
818 812
    {
819 813
      return new ReachedMap(g);
820 814
    }
821 815

	
822 816
    ///The type of the map that stores the distances of the nodes.
823 817

	
824 818
    ///The type of the map that stores the distances of the nodes.
825 819
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
826 820
    typedef typename Digraph::template NodeMap<int> DistMap;
827 821
    ///Instantiates a \ref DistMap.
828 822

	
829 823
    ///This function instantiates a \ref DistMap.
830 824
    ///\param g is the digraph, to which we would like to define
831 825
    ///the \ref DistMap
832 826
    static DistMap *createDistMap(const Digraph &g)
833 827
    {
834 828
      return new DistMap(g);
835 829
    }
836 830

	
837 831
    ///The type of the DFS paths.
838 832

	
839 833
    ///The type of the DFS paths.
840 834
    ///It must meet the \ref concepts::Path "Path" concept.
841 835
    typedef lemon::Path<Digraph> Path;
842 836
  };
843 837

	
844 838
  /// Default traits class used by \ref DfsWizard
845 839

	
846 840
  /// To make it easier to use Dfs algorithm
847 841
  /// we have created a wizard class.
848 842
  /// This \ref DfsWizard class needs default traits,
849 843
  /// as well as the \ref Dfs class.
850 844
  /// The \ref DfsWizardBase is a class to be the default traits of the
851 845
  /// \ref DfsWizard class.
852 846
  template<class GR>
853 847
  class DfsWizardBase : public DfsWizardDefaultTraits<GR>
854 848
  {
855 849

	
856 850
    typedef DfsWizardDefaultTraits<GR> Base;
857 851
  protected:
858 852
    //The type of the nodes in the digraph.
859 853
    typedef typename Base::Digraph::Node Node;
860 854

	
861 855
    //Pointer to the digraph the algorithm runs on.
862 856
    void *_g;
863 857
    //Pointer to the map of reached nodes.
864 858
    void *_reached;
865 859
    //Pointer to the map of processed nodes.
866 860
    void *_processed;
867 861
    //Pointer to the map of predecessors arcs.
868 862
    void *_pred;
869 863
    //Pointer to the map of distances.
870 864
    void *_dist;
871 865
    //Pointer to the DFS path to the target node.
872 866
    void *_path;
873 867
    //Pointer to the distance of the target node.
874 868
    int *_di;
875 869

	
876 870
    public:
877 871
    /// Constructor.
878 872

	
879 873
    /// This constructor does not require parameters, therefore it initiates
880 874
    /// all of the attributes to \c 0.
881 875
    DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
882 876
                      _dist(0), _path(0), _di(0) {}
883 877

	
884 878
    /// Constructor.
885 879

	
886 880
    /// This constructor requires one parameter,
887 881
    /// others are initiated to \c 0.
888 882
    /// \param g The digraph the algorithm runs on.
889 883
    DfsWizardBase(const GR &g) :
890 884
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
891 885
      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
892 886

	
893 887
  };
894 888

	
895 889
  /// Auxiliary class for the function-type interface of DFS algorithm.
896 890

	
897 891
  /// This auxiliary class is created to implement the
898 892
  /// \ref dfs() "function-type interface" of \ref Dfs algorithm.
899 893
  /// It does not have own \ref run() method, it uses the functions
900 894
  /// and features of the plain \ref Dfs.
901 895
  ///
902 896
  /// This class should only be used through the \ref dfs() function,
903 897
  /// which makes it easier to use the algorithm.
904 898
  template<class TR>
905 899
  class DfsWizard : public TR
906 900
  {
907 901
    typedef TR Base;
908 902

	
909 903
    ///The type of the digraph the algorithm runs on.
910 904
    typedef typename TR::Digraph Digraph;
911 905

	
912 906
    typedef typename Digraph::Node Node;
913 907
    typedef typename Digraph::NodeIt NodeIt;
914 908
    typedef typename Digraph::Arc Arc;
915 909
    typedef typename Digraph::OutArcIt OutArcIt;
916 910

	
917 911
    ///\brief The type of the map that stores the predecessor
918 912
    ///arcs of the DFS paths.
919 913
    typedef typename TR::PredMap PredMap;
920 914
    ///\brief The type of the map that stores the distances of the nodes.
921 915
    typedef typename TR::DistMap DistMap;
922 916
    ///\brief The type of the map that indicates which nodes are reached.
923 917
    typedef typename TR::ReachedMap ReachedMap;
924 918
    ///\brief The type of the map that indicates which nodes are processed.
925 919
    typedef typename TR::ProcessedMap ProcessedMap;
926 920
    ///The type of the DFS paths
927 921
    typedef typename TR::Path Path;
928 922

	
929 923
  public:
930 924

	
931 925
    /// Constructor.
932 926
    DfsWizard() : TR() {}
933 927

	
934 928
    /// Constructor that requires parameters.
935 929

	
936 930
    /// Constructor that requires parameters.
937 931
    /// These parameters will be the default values for the traits class.
938 932
    /// \param g The digraph the algorithm runs on.
939 933
    DfsWizard(const Digraph &g) :
940 934
      TR(g) {}
941 935

	
942 936
    ///Copy constructor
943 937
    DfsWizard(const TR &b) : TR(b) {}
944 938

	
945 939
    ~DfsWizard() {}
946 940

	
947 941
    ///Runs DFS algorithm from the given source node.
948 942

	
949 943
    ///This method runs DFS algorithm from node \c s
950 944
    ///in order to compute the DFS path to each node.
951 945
    void run(Node s)
952 946
    {
953 947
      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
954 948
      if (Base::_pred)
955 949
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
956 950
      if (Base::_dist)
957 951
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
958 952
      if (Base::_reached)
959 953
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
960 954
      if (Base::_processed)
961 955
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
962 956
      if (s!=INVALID)
963 957
        alg.run(s);
964 958
      else
965 959
        alg.run();
966 960
    }
967 961

	
968 962
    ///Finds the DFS path between \c s and \c t.
969 963

	
970 964
    ///This method runs DFS algorithm from node \c s
971 965
    ///in order to compute the DFS path to node \c t
972 966
    ///(it stops searching when \c t is processed).
973 967
    ///
974 968
    ///\return \c true if \c t is reachable form \c s.
975 969
    bool run(Node s, Node t)
976 970
    {
977
      if (s==INVALID || t==INVALID) throw UninitializedParameter();
978 971
      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
979 972
      if (Base::_pred)
980 973
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
981 974
      if (Base::_dist)
982 975
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
983 976
      if (Base::_reached)
984 977
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
985 978
      if (Base::_processed)
986 979
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
987 980
      alg.run(s,t);
988 981
      if (Base::_path)
989 982
        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
990 983
      if (Base::_di)
991 984
        *Base::_di = alg.dist(t);
992 985
      return alg.reached(t);
993 986
      }
994 987

	
995 988
    ///Runs DFS algorithm to visit all nodes in the digraph.
996 989

	
997 990
    ///This method runs DFS algorithm in order to compute
998 991
    ///the DFS path to each node.
999 992
    void run()
1000 993
    {
1001 994
      run(INVALID);
1002 995
    }
1003 996

	
1004 997
    template<class T>
1005 998
    struct SetPredMapBase : public Base {
1006 999
      typedef T PredMap;
1007 1000
      static PredMap *createPredMap(const Digraph &) { return 0; };
1008 1001
      SetPredMapBase(const TR &b) : TR(b) {}
1009 1002
    };
1010 1003
    ///\brief \ref named-func-param "Named parameter"
1011 1004
    ///for setting \ref PredMap object.
1012 1005
    ///
1013 1006
    ///\ref named-func-param "Named parameter"
1014 1007
    ///for setting \ref PredMap object.
1015 1008
    template<class T>
1016 1009
    DfsWizard<SetPredMapBase<T> > predMap(const T &t)
1017 1010
    {
1018 1011
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1019 1012
      return DfsWizard<SetPredMapBase<T> >(*this);
1020 1013
    }
1021 1014

	
1022 1015
    template<class T>
1023 1016
    struct SetReachedMapBase : public Base {
1024 1017
      typedef T ReachedMap;
1025 1018
      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
1026 1019
      SetReachedMapBase(const TR &b) : TR(b) {}
1027 1020
    };
1028 1021
    ///\brief \ref named-func-param "Named parameter"
1029 1022
    ///for setting \ref ReachedMap object.
1030 1023
    ///
1031 1024
    /// \ref named-func-param "Named parameter"
1032 1025
    ///for setting \ref ReachedMap object.
1033 1026
    template<class T>
1034 1027
    DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
1035 1028
    {
1036 1029
      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
1037 1030
      return DfsWizard<SetReachedMapBase<T> >(*this);
1038 1031
    }
1039 1032

	
1040 1033
    template<class T>
1041 1034
    struct SetDistMapBase : public Base {
1042 1035
      typedef T DistMap;
1043 1036
      static DistMap *createDistMap(const Digraph &) { return 0; };
1044 1037
      SetDistMapBase(const TR &b) : TR(b) {}
1045 1038
    };
1046 1039
    ///\brief \ref named-func-param "Named parameter"
1047 1040
    ///for setting \ref DistMap object.
1048 1041
    ///
1049 1042
    /// \ref named-func-param "Named parameter"
1050 1043
    ///for setting \ref DistMap object.
1051 1044
    template<class T>
1052 1045
    DfsWizard<SetDistMapBase<T> > distMap(const T &t)
1053 1046
    {
1054 1047
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1055 1048
      return DfsWizard<SetDistMapBase<T> >(*this);
1056 1049
    }
1057 1050

	
1058 1051
    template<class T>
1059 1052
    struct SetProcessedMapBase : public Base {
1060 1053
      typedef T ProcessedMap;
1061 1054
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1062 1055
      SetProcessedMapBase(const TR &b) : TR(b) {}
1063 1056
    };
1064 1057
    ///\brief \ref named-func-param "Named parameter"
1065 1058
    ///for setting \ref ProcessedMap object.
1066 1059
    ///
1067 1060
    /// \ref named-func-param "Named parameter"
1068 1061
    ///for setting \ref ProcessedMap object.
1069 1062
    template<class T>
1070 1063
    DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
1071 1064
    {
1072 1065
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1073 1066
      return DfsWizard<SetProcessedMapBase<T> >(*this);
1074 1067
    }
1075 1068

	
1076 1069
    template<class T>
1077 1070
    struct SetPathBase : public Base {
1078 1071
      typedef T Path;
1079 1072
      SetPathBase(const TR &b) : TR(b) {}
1080 1073
    };
1081 1074
    ///\brief \ref named-func-param "Named parameter"
1082 1075
    ///for getting the DFS path to the target node.
1083 1076
    ///
1084 1077
    ///\ref named-func-param "Named parameter"
1085 1078
    ///for getting the DFS path to the target node.
1086 1079
    template<class T>
1087 1080
    DfsWizard<SetPathBase<T> > path(const T &t)
1088 1081
    {
1089 1082
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1090 1083
      return DfsWizard<SetPathBase<T> >(*this);
1091 1084
    }
1092 1085

	
1093 1086
    ///\brief \ref named-func-param "Named parameter"
1094 1087
    ///for getting the distance of the target node.
1095 1088
    ///
1096 1089
    ///\ref named-func-param "Named parameter"
1097 1090
    ///for getting the distance of the target node.
1098 1091
    DfsWizard dist(const int &d)
1099 1092
    {
1100 1093
      Base::_di=const_cast<int*>(&d);
1101 1094
      return *this;
1102 1095
    }
1103 1096

	
1104 1097
  };
1105 1098

	
1106 1099
  ///Function-type interface for DFS algorithm.
1107 1100

	
1108 1101
  ///\ingroup search
1109 1102
  ///Function-type interface for DFS algorithm.
1110 1103
  ///
1111 1104
  ///This function also has several \ref named-func-param "named parameters",
1112 1105
  ///they are declared as the members of class \ref DfsWizard.
1113 1106
  ///The following examples show how to use these parameters.
1114 1107
  ///\code
1115 1108
  ///  // Compute the DFS tree
1116 1109
  ///  dfs(g).predMap(preds).distMap(dists).run(s);
1117 1110
  ///
1118 1111
  ///  // Compute the DFS path from s to t
1119 1112
  ///  bool reached = dfs(g).path(p).dist(d).run(s,t);
1120 1113
  ///\endcode
1121 1114

	
1122 1115
  ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
1123 1116
  ///to the end of the parameter list.
1124 1117
  ///\sa DfsWizard
1125 1118
  ///\sa Dfs
1126 1119
  template<class GR>
1127 1120
  DfsWizard<DfsWizardBase<GR> >
1128 1121
  dfs(const GR &digraph)
1129 1122
  {
1130 1123
    return DfsWizard<DfsWizardBase<GR> >(digraph);
1131 1124
  }
1132 1125

	
1133 1126
#ifdef DOXYGEN
1134 1127
  /// \brief Visitor class for DFS.
1135 1128
  ///
1136 1129
  /// This class defines the interface of the DfsVisit events, and
1137 1130
  /// it could be the base of a real visitor class.
1138 1131
  template <typename _Digraph>
1139 1132
  struct DfsVisitor {
1140 1133
    typedef _Digraph Digraph;
1141 1134
    typedef typename Digraph::Arc Arc;
1142 1135
    typedef typename Digraph::Node Node;
1143 1136
    /// \brief Called for the source node of the DFS.
1144 1137
    ///
1145 1138
    /// This function is called for the source node of the DFS.
1146 1139
    void start(const Node& node) {}
1147 1140
    /// \brief Called when the source node is leaved.
1148 1141
    ///
1149 1142
    /// This function is called when the source node is leaved.
1150 1143
    void stop(const Node& node) {}
1151 1144
    /// \brief Called when a node is reached first time.
1152 1145
    ///
1153 1146
    /// This function is called when a node is reached first time.
1154 1147
    void reach(const Node& node) {}
1155 1148
    /// \brief Called when an arc reaches a new node.
1156 1149
    ///
1157 1150
    /// This function is called when the DFS finds an arc whose target node
1158 1151
    /// is not reached yet.
1159 1152
    void discover(const Arc& arc) {}
1160 1153
    /// \brief Called when an arc is examined but its target node is
1161 1154
    /// already discovered.
1162 1155
    ///
1163 1156
    /// This function is called when an arc is examined but its target node is
1164 1157
    /// already discovered.
1165 1158
    void examine(const Arc& arc) {}
1166 1159
    /// \brief Called when the DFS steps back from a node.
1167 1160
    ///
1168 1161
    /// This function is called when the DFS steps back from a node.
1169 1162
    void leave(const Node& node) {}
1170 1163
    /// \brief Called when the DFS steps back on an arc.
1171 1164
    ///
1172 1165
    /// This function is called when the DFS steps back on an arc.
1173 1166
    void backtrack(const Arc& arc) {}
1174 1167
  };
1175 1168
#else
1176 1169
  template <typename _Digraph>
1177 1170
  struct DfsVisitor {
1178 1171
    typedef _Digraph Digraph;
1179 1172
    typedef typename Digraph::Arc Arc;
1180 1173
    typedef typename Digraph::Node Node;
1181 1174
    void start(const Node&) {}
1182 1175
    void stop(const Node&) {}
1183 1176
    void reach(const Node&) {}
1184 1177
    void discover(const Arc&) {}
1185 1178
    void examine(const Arc&) {}
1186 1179
    void leave(const Node&) {}
1187 1180
    void backtrack(const Arc&) {}
1188 1181

	
1189 1182
    template <typename _Visitor>
1190 1183
    struct Constraints {
1191 1184
      void constraints() {
1192 1185
        Arc arc;
1193 1186
        Node node;
1194 1187
        visitor.start(node);
1195 1188
        visitor.stop(arc);
1196 1189
        visitor.reach(node);
1197 1190
        visitor.discover(arc);
1198 1191
        visitor.examine(arc);
1199 1192
        visitor.leave(node);
1200 1193
        visitor.backtrack(arc);
1201 1194
      }
1202 1195
      _Visitor& visitor;
1203 1196
    };
1204 1197
  };
1205 1198
#endif
1206 1199

	
1207 1200
  /// \brief Default traits class of DfsVisit class.
1208 1201
  ///
1209 1202
  /// Default traits class of DfsVisit class.
1210 1203
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1211 1204
  template<class _Digraph>
1212 1205
  struct DfsVisitDefaultTraits {
1213 1206

	
1214 1207
    /// \brief The type of the digraph the algorithm runs on.
1215 1208
    typedef _Digraph Digraph;
1216 1209

	
1217 1210
    /// \brief The type of the map that indicates which nodes are reached.
1218 1211
    ///
1219 1212
    /// The type of the map that indicates which nodes are reached.
1220 1213
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1221 1214
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
1222 1215

	
1223 1216
    /// \brief Instantiates a \ref ReachedMap.
1224 1217
    ///
1225 1218
    /// This function instantiates a \ref ReachedMap.
1226 1219
    /// \param digraph is the digraph, to which
1227 1220
    /// we would like to define the \ref ReachedMap.
1228 1221
    static ReachedMap *createReachedMap(const Digraph &digraph) {
1229 1222
      return new ReachedMap(digraph);
1230 1223
    }
1231 1224

	
1232 1225
  };
1233 1226

	
1234 1227
  /// \ingroup search
1235 1228
  ///
1236 1229
  /// \brief %DFS algorithm class with visitor interface.
1237 1230
  ///
1238 1231
  /// This class provides an efficient implementation of the %DFS algorithm
1239 1232
  /// with visitor interface.
1240 1233
  ///
1241 1234
  /// The %DfsVisit class provides an alternative interface to the Dfs
1242 1235
  /// class. It works with callback mechanism, the DfsVisit object calls
1243 1236
  /// the member functions of the \c Visitor class on every DFS event.
1244 1237
  ///
1245 1238
  /// This interface of the DFS algorithm should be used in special cases
1246 1239
  /// when extra actions have to be performed in connection with certain
1247 1240
  /// events of the DFS algorithm. Otherwise consider to use Dfs or dfs()
1248 1241
  /// instead.
1249 1242
  ///
1250 1243
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1251 1244
  /// The default value is
1252 1245
  /// \ref ListDigraph. The value of _Digraph is not used directly by
1253 1246
  /// \ref DfsVisit, it is only passed to \ref DfsVisitDefaultTraits.
1254 1247
  /// \tparam _Visitor The Visitor type that is used by the algorithm.
1255 1248
  /// \ref DfsVisitor "DfsVisitor<_Digraph>" is an empty visitor, which
1256 1249
  /// does not observe the DFS events. If you want to observe the DFS
1257 1250
  /// events, you should implement your own visitor class.
1258 1251
  /// \tparam _Traits Traits class to set various data types used by the
1259 1252
  /// algorithm. The default traits class is
1260 1253
  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<_Digraph>".
1261 1254
  /// See \ref DfsVisitDefaultTraits for the documentation of
1262 1255
  /// a DFS visit traits class.
1263 1256
#ifdef DOXYGEN
1264 1257
  template <typename _Digraph, typename _Visitor, typename _Traits>
1265 1258
#else
1266 1259
  template <typename _Digraph = ListDigraph,
1267 1260
            typename _Visitor = DfsVisitor<_Digraph>,
1268 1261
            typename _Traits = DfsDefaultTraits<_Digraph> >
1269 1262
#endif
1270 1263
  class DfsVisit {
1271 1264
  public:
1272 1265

	
1273
    /// \brief \ref Exception for uninitialized parameters.
1274
    ///
1275
    /// This error represents problems in the initialization
1276
    /// of the parameters of the algorithm.
1277
    class UninitializedParameter : public lemon::UninitializedParameter {
1278
    public:
1279
      virtual const char* what() const throw()
1280
      {
1281
        return "lemon::DfsVisit::UninitializedParameter";
1282
      }
1283
    };
1284

	
1285 1266
    ///The traits class.
1286 1267
    typedef _Traits Traits;
1287 1268

	
1288 1269
    ///The type of the digraph the algorithm runs on.
1289 1270
    typedef typename Traits::Digraph Digraph;
1290 1271

	
1291 1272
    ///The visitor type used by the algorithm.
1292 1273
    typedef _Visitor Visitor;
1293 1274

	
1294 1275
    ///The type of the map that indicates which nodes are reached.
1295 1276
    typedef typename Traits::ReachedMap ReachedMap;
1296 1277

	
1297 1278
  private:
1298 1279

	
1299 1280
    typedef typename Digraph::Node Node;
1300 1281
    typedef typename Digraph::NodeIt NodeIt;
1301 1282
    typedef typename Digraph::Arc Arc;
1302 1283
    typedef typename Digraph::OutArcIt OutArcIt;
1303 1284

	
1304 1285
    //Pointer to the underlying digraph.
1305 1286
    const Digraph *_digraph;
1306 1287
    //Pointer to the visitor object.
1307 1288
    Visitor *_visitor;
1308 1289
    //Pointer to the map of reached status of the nodes.
1309 1290
    ReachedMap *_reached;
1310 1291
    //Indicates if _reached is locally allocated (true) or not.
1311 1292
    bool local_reached;
1312 1293

	
1313 1294
    std::vector<typename Digraph::Arc> _stack;
1314 1295
    int _stack_head;
1315 1296

	
1316 1297
    //Creates the maps if necessary.
1317 1298
    void create_maps() {
1318 1299
      if(!_reached) {
1319 1300
        local_reached = true;
1320 1301
        _reached = Traits::createReachedMap(*_digraph);
1321 1302
      }
1322 1303
    }
1323 1304

	
1324 1305
  protected:
1325 1306

	
1326 1307
    DfsVisit() {}
1327 1308

	
1328 1309
  public:
1329 1310

	
1330 1311
    typedef DfsVisit Create;
1331 1312

	
1332 1313
    /// \name Named template parameters
1333 1314

	
1334 1315
    ///@{
1335 1316
    template <class T>
1336 1317
    struct SetReachedMapTraits : public Traits {
1337 1318
      typedef T ReachedMap;
1338 1319
      static ReachedMap *createReachedMap(const Digraph &digraph) {
1339
        throw UninitializedParameter();
1320
        LEMON_ASSERT(false, "ReachedMap is not initialized");
1321
        return 0; // ignore warnings
1340 1322
      }
1341 1323
    };
1342 1324
    /// \brief \ref named-templ-param "Named parameter" for setting
1343 1325
    /// ReachedMap type.
1344 1326
    ///
1345 1327
    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
1346 1328
    template <class T>
1347 1329
    struct SetReachedMap : public DfsVisit< Digraph, Visitor,
1348 1330
                                            SetReachedMapTraits<T> > {
1349 1331
      typedef DfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
1350 1332
    };
1351 1333
    ///@}
1352 1334

	
1353 1335
  public:
1354 1336

	
1355 1337
    /// \brief Constructor.
1356 1338
    ///
1357 1339
    /// Constructor.
1358 1340
    ///
1359 1341
    /// \param digraph The digraph the algorithm runs on.
1360 1342
    /// \param visitor The visitor object of the algorithm.
1361 1343
    DfsVisit(const Digraph& digraph, Visitor& visitor)
1362 1344
      : _digraph(&digraph), _visitor(&visitor),
1363 1345
        _reached(0), local_reached(false) {}
1364 1346

	
1365 1347
    /// \brief Destructor.
1366 1348
    ~DfsVisit() {
1367 1349
      if(local_reached) delete _reached;
1368 1350
    }
1369 1351

	
1370 1352
    /// \brief Sets the map that indicates which nodes are reached.
1371 1353
    ///
1372 1354
    /// Sets the map that indicates which nodes are reached.
1373 1355
    /// If you don't use this function before calling \ref run(),
1374 1356
    /// it will allocate one. The destructor deallocates this
1375 1357
    /// automatically allocated map, of course.
1376 1358
    /// \return <tt> (*this) </tt>
1377 1359
    DfsVisit &reachedMap(ReachedMap &m) {
1378 1360
      if(local_reached) {
1379 1361
        delete _reached;
1380 1362
        local_reached=false;
1381 1363
      }
1382 1364
      _reached = &m;
1383 1365
      return *this;
1384 1366
    }
1385 1367

	
1386 1368
  public:
1387 1369

	
1388 1370
    /// \name Execution control
1389 1371
    /// The simplest way to execute the algorithm is to use
1390 1372
    /// one of the member functions called \ref lemon::DfsVisit::run()
1391 1373
    /// "run()".
1392 1374
    /// \n
1393 1375
    /// If you need more control on the execution, first you must call
1394 1376
    /// \ref lemon::DfsVisit::init() "init()", then you can add several
1395 1377
    /// source nodes with \ref lemon::DfsVisit::addSource() "addSource()".
1396 1378
    /// Finally \ref lemon::DfsVisit::start() "start()" will perform the
1397 1379
    /// actual path computation.
1398 1380

	
1399 1381
    /// @{
1400 1382

	
1401 1383
    /// \brief Initializes the internal data structures.
1402 1384
    ///
1403 1385
    /// Initializes the internal data structures.
1404 1386
    void init() {
1405 1387
      create_maps();
1406 1388
      _stack.resize(countNodes(*_digraph));
1407 1389
      _stack_head = -1;
1408 1390
      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
1409 1391
        _reached->set(u, false);
1410 1392
      }
1411 1393
    }
1412 1394

	
1413 1395
    ///Adds a new source node.
1414 1396

	
1415 1397
    ///Adds a new source node to the set of nodes to be processed.
1416 1398
    ///
1417 1399
    ///\pre The stack must be empty. (Otherwise the algorithm gives
1418 1400
    ///false results.)
1419 1401
    ///
1420 1402
    ///\warning Distances will be wrong (or at least strange) in case of
1421 1403
    ///multiple sources.
1422 1404
    void addSource(Node s)
1423 1405
    {
1424 1406
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
1425 1407
      if(!(*_reached)[s]) {
1426 1408
          _reached->set(s,true);
1427 1409
          _visitor->start(s);
1428 1410
          _visitor->reach(s);
1429 1411
          Arc e;
1430 1412
          _digraph->firstOut(e, s);
1431 1413
          if (e != INVALID) {
1432 1414
            _stack[++_stack_head] = e;
1433 1415
          } else {
1434 1416
            _visitor->leave(s);
1435 1417
          }
1436 1418
        }
1437 1419
    }
1438 1420

	
1439 1421
    /// \brief Processes the next arc.
1440 1422
    ///
1441 1423
    /// Processes the next arc.
1442 1424
    ///
1443 1425
    /// \return The processed arc.
1444 1426
    ///
1445 1427
    /// \pre The stack must not be empty.
1446 1428
    Arc processNextArc() {
1447 1429
      Arc e = _stack[_stack_head];
1448 1430
      Node m = _digraph->target(e);
1449 1431
      if(!(*_reached)[m]) {
1450 1432
        _visitor->discover(e);
1451 1433
        _visitor->reach(m);
1452 1434
        _reached->set(m, true);
1453 1435
        _digraph->firstOut(_stack[++_stack_head], m);
1454 1436
      } else {
1455 1437
        _visitor->examine(e);
1456 1438
        m = _digraph->source(e);
1457 1439
        _digraph->nextOut(_stack[_stack_head]);
1458 1440
      }
1459 1441
      while (_stack_head>=0 && _stack[_stack_head] == INVALID) {
1460 1442
        _visitor->leave(m);
1461 1443
        --_stack_head;
1462 1444
        if (_stack_head >= 0) {
1463 1445
          _visitor->backtrack(_stack[_stack_head]);
1464 1446
          m = _digraph->source(_stack[_stack_head]);
1465 1447
          _digraph->nextOut(_stack[_stack_head]);
1466 1448
        } else {
1467 1449
          _visitor->stop(m);
1468 1450
        }
1469 1451
      }
1470 1452
      return e;
1471 1453
    }
1472 1454

	
1473 1455
    /// \brief Next arc to be processed.
1474 1456
    ///
1475 1457
    /// Next arc to be processed.
1476 1458
    ///
1477 1459
    /// \return The next arc to be processed or INVALID if the stack is
1478 1460
    /// empty.
1479 1461
    Arc nextArc() const {
1480 1462
      return _stack_head >= 0 ? _stack[_stack_head] : INVALID;
1481 1463
    }
1482 1464

	
1483 1465
    /// \brief Returns \c false if there are nodes
1484 1466
    /// to be processed.
1485 1467
    ///
1486 1468
    /// Returns \c false if there are nodes
1487 1469
    /// to be processed in the queue (stack).
1488 1470
    bool emptyQueue() const { return _stack_head < 0; }
1489 1471

	
1490 1472
    /// \brief Returns the number of the nodes to be processed.
1491 1473
    ///
1492 1474
    /// Returns the number of the nodes to be processed in the queue (stack).
1493 1475
    int queueSize() const { return _stack_head + 1; }
1494 1476

	
1495 1477
    /// \brief Executes the algorithm.
1496 1478
    ///
1497 1479
    /// Executes the algorithm.
1498 1480
    ///
1499 1481
    /// This method runs the %DFS algorithm from the root node
1500 1482
    /// in order to compute the %DFS path to each node.
1501 1483
    ///
1502 1484
    /// The algorithm computes
1503 1485
    /// - the %DFS tree,
1504 1486
    /// - the distance of each node from the root in the %DFS tree.
1505 1487
    ///
1506 1488
    /// \pre init() must be called and a root node should be
1507 1489
    /// added with addSource() before using this function.
1508 1490
    ///
1509 1491
    /// \note <tt>d.start()</tt> is just a shortcut of the following code.
1510 1492
    /// \code
1511 1493
    ///   while ( !d.emptyQueue() ) {
1512 1494
    ///     d.processNextArc();
1513 1495
    ///   }
1514 1496
    /// \endcode
1515 1497
    void start() {
1516 1498
      while ( !emptyQueue() ) processNextArc();
1517 1499
    }
1518 1500

	
1519 1501
    /// \brief Executes the algorithm until the given target node is reached.
1520 1502
    ///
1521 1503
    /// Executes the algorithm until the given target node is reached.
1522 1504
    ///
1523 1505
    /// This method runs the %DFS algorithm from the root node
1524 1506
    /// in order to compute the DFS path to \c t.
1525 1507
    ///
1526 1508
    /// The algorithm computes
1527 1509
    /// - the %DFS path to \c t,
1528 1510
    /// - the distance of \c t from the root in the %DFS tree.
1529 1511
    ///
1530 1512
    /// \pre init() must be called and a root node should be added
1531 1513
    /// with addSource() before using this function.
Ignore white space 6 line context
... ...
@@ -36,572 +36,567 @@
36 36

	
37 37
  /// \brief Default operation traits for the Dijkstra algorithm class.
38 38
  ///
39 39
  /// This operation traits class defines all computational operations and
40 40
  /// constants which are used in the Dijkstra algorithm.
41 41
  template <typename Value>
42 42
  struct DijkstraDefaultOperationTraits {
43 43
    /// \brief Gives back the zero value of the type.
44 44
    static Value zero() {
45 45
      return static_cast<Value>(0);
46 46
    }
47 47
    /// \brief Gives back the sum of the given two elements.
48 48
    static Value plus(const Value& left, const Value& right) {
49 49
      return left + right;
50 50
    }
51 51
    /// \brief Gives back true only if the first value is less than the second.
52 52
    static bool less(const Value& left, const Value& right) {
53 53
      return left < right;
54 54
    }
55 55
  };
56 56

	
57 57
  /// \brief Widest path operation traits for the Dijkstra algorithm class.
58 58
  ///
59 59
  /// This operation traits class defines all computational operations and
60 60
  /// constants which are used in the Dijkstra algorithm for widest path
61 61
  /// computation.
62 62
  ///
63 63
  /// \see DijkstraDefaultOperationTraits
64 64
  template <typename Value>
65 65
  struct DijkstraWidestPathOperationTraits {
66 66
    /// \brief Gives back the maximum value of the type.
67 67
    static Value zero() {
68 68
      return std::numeric_limits<Value>::max();
69 69
    }
70 70
    /// \brief Gives back the minimum of the given two elements.
71 71
    static Value plus(const Value& left, const Value& right) {
72 72
      return std::min(left, right);
73 73
    }
74 74
    /// \brief Gives back true only if the first value is less than the second.
75 75
    static bool less(const Value& left, const Value& right) {
76 76
      return left < right;
77 77
    }
78 78
  };
79 79

	
80 80
  ///Default traits class of Dijkstra class.
81 81

	
82 82
  ///Default traits class of Dijkstra class.
83 83
  ///\tparam GR The type of the digraph.
84 84
  ///\tparam LM The type of the length map.
85 85
  template<class GR, class LM>
86 86
  struct DijkstraDefaultTraits
87 87
  {
88 88
    ///The type of the digraph the algorithm runs on.
89 89
    typedef GR Digraph;
90 90

	
91 91
    ///The type of the map that stores the arc lengths.
92 92

	
93 93
    ///The type of the map that stores the arc lengths.
94 94
    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
95 95
    typedef LM LengthMap;
96 96
    ///The type of the length of the arcs.
97 97
    typedef typename LM::Value Value;
98 98

	
99 99
    /// Operation traits for Dijkstra algorithm.
100 100

	
101 101
    /// This class defines the operations that are used in the algorithm.
102 102
    /// \see DijkstraDefaultOperationTraits
103 103
    typedef DijkstraDefaultOperationTraits<Value> OperationTraits;
104 104

	
105 105
    /// The cross reference type used by the heap.
106 106

	
107 107
    /// The cross reference type used by the heap.
108 108
    /// Usually it is \c Digraph::NodeMap<int>.
109 109
    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
110 110
    ///Instantiates a \ref HeapCrossRef.
111 111

	
112 112
    ///This function instantiates a \ref HeapCrossRef.
113 113
    /// \param g is the digraph, to which we would like to define the
114 114
    /// \ref HeapCrossRef.
115 115
    static HeapCrossRef *createHeapCrossRef(const Digraph &g)
116 116
    {
117 117
      return new HeapCrossRef(g);
118 118
    }
119 119

	
120 120
    ///The heap type used by the Dijkstra algorithm.
121 121

	
122 122
    ///The heap type used by the Dijkstra algorithm.
123 123
    ///
124 124
    ///\sa BinHeap
125 125
    ///\sa Dijkstra
126 126
    typedef BinHeap<typename LM::Value, HeapCrossRef, std::less<Value> > Heap;
127 127
    ///Instantiates a \ref Heap.
128 128

	
129 129
    ///This function instantiates a \ref Heap.
130 130
    static Heap *createHeap(HeapCrossRef& r)
131 131
    {
132 132
      return new Heap(r);
133 133
    }
134 134

	
135 135
    ///\brief The type of the map that stores the predecessor
136 136
    ///arcs of the shortest paths.
137 137
    ///
138 138
    ///The type of the map that stores the predecessor
139 139
    ///arcs of the shortest paths.
140 140
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
141 141
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
142 142
    ///Instantiates a \ref PredMap.
143 143

	
144 144
    ///This function instantiates a \ref PredMap.
145 145
    ///\param g is the digraph, to which we would like to define the
146 146
    ///\ref PredMap.
147 147
    static PredMap *createPredMap(const Digraph &g)
148 148
    {
149 149
      return new PredMap(g);
150 150
    }
151 151

	
152 152
    ///The type of the map that indicates which nodes are processed.
153 153

	
154 154
    ///The type of the map that indicates which nodes are processed.
155 155
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
156 156
    ///By default it is a NullMap.
157 157
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
158 158
    ///Instantiates a \ref ProcessedMap.
159 159

	
160 160
    ///This function instantiates a \ref ProcessedMap.
161 161
    ///\param g is the digraph, to which
162 162
    ///we would like to define the \ref ProcessedMap
163 163
#ifdef DOXYGEN
164 164
    static ProcessedMap *createProcessedMap(const Digraph &g)
165 165
#else
166 166
    static ProcessedMap *createProcessedMap(const Digraph &)
167 167
#endif
168 168
    {
169 169
      return new ProcessedMap();
170 170
    }
171 171

	
172 172
    ///The type of the map that stores the distances of the nodes.
173 173

	
174 174
    ///The type of the map that stores the distances of the nodes.
175 175
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
176 176
    typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
177 177
    ///Instantiates a \ref DistMap.
178 178

	
179 179
    ///This function instantiates a \ref DistMap.
180 180
    ///\param g is the digraph, to which we would like to define
181 181
    ///the \ref DistMap
182 182
    static DistMap *createDistMap(const Digraph &g)
183 183
    {
184 184
      return new DistMap(g);
185 185
    }
186 186
  };
187 187

	
188 188
  ///%Dijkstra algorithm class.
189 189

	
190 190
  /// \ingroup shortest_path
191 191
  ///This class provides an efficient implementation of the %Dijkstra algorithm.
192 192
  ///
193 193
  ///The arc lengths are passed to the algorithm using a
194 194
  ///\ref concepts::ReadMap "ReadMap",
195 195
  ///so it is easy to change it to any kind of length.
196 196
  ///The type of the length is determined by the
197 197
  ///\ref concepts::ReadMap::Value "Value" of the length map.
198 198
  ///It is also possible to change the underlying priority heap.
199 199
  ///
200 200
  ///There is also a \ref dijkstra() "function-type interface" for the
201 201
  ///%Dijkstra algorithm, which is convenient in the simplier cases and
202 202
  ///it can be used easier.
203 203
  ///
204 204
  ///\tparam GR The type of the digraph the algorithm runs on.
205 205
  ///The default value is \ref ListDigraph.
206 206
  ///The value of GR is not used directly by \ref Dijkstra, it is only
207 207
  ///passed to \ref DijkstraDefaultTraits.
208 208
  ///\tparam LM A readable arc map that determines the lengths of the
209 209
  ///arcs. It is read once for each arc, so the map may involve in
210 210
  ///relatively time consuming process to compute the arc lengths if
211 211
  ///it is necessary. The default map type is \ref
212 212
  ///concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
213 213
  ///The value of LM is not used directly by \ref Dijkstra, it is only
214 214
  ///passed to \ref DijkstraDefaultTraits.
215 215
  ///\tparam TR Traits class to set various data types used by the algorithm.
216 216
  ///The default traits class is \ref DijkstraDefaultTraits
217 217
  ///"DijkstraDefaultTraits<GR,LM>". See \ref DijkstraDefaultTraits
218 218
  ///for the documentation of a Dijkstra traits class.
219 219
#ifdef DOXYGEN
220 220
  template <typename GR, typename LM, typename TR>
221 221
#else
222 222
  template <typename GR=ListDigraph,
223 223
            typename LM=typename GR::template ArcMap<int>,
224 224
            typename TR=DijkstraDefaultTraits<GR,LM> >
225 225
#endif
226 226
  class Dijkstra {
227 227
  public:
228
    ///\ref Exception for uninitialized parameters.
229

	
230
    ///This error represents problems in the initialization of the
231
    ///parameters of the algorithm.
232
    class UninitializedParameter : public lemon::UninitializedParameter {
233
    public:
234
      virtual const char* what() const throw() {
235
        return "lemon::Dijkstra::UninitializedParameter";
236
      }
237
    };
238 228

	
239 229
    ///The type of the digraph the algorithm runs on.
240 230
    typedef typename TR::Digraph Digraph;
241 231

	
242 232
    ///The type of the length of the arcs.
243 233
    typedef typename TR::LengthMap::Value Value;
244 234
    ///The type of the map that stores the arc lengths.
245 235
    typedef typename TR::LengthMap LengthMap;
246 236
    ///\brief The type of the map that stores the predecessor arcs of the
247 237
    ///shortest paths.
248 238
    typedef typename TR::PredMap PredMap;
249 239
    ///The type of the map that stores the distances of the nodes.
250 240
    typedef typename TR::DistMap DistMap;
251 241
    ///The type of the map that indicates which nodes are processed.
252 242
    typedef typename TR::ProcessedMap ProcessedMap;
253 243
    ///The type of the paths.
254 244
    typedef PredMapPath<Digraph, PredMap> Path;
255 245
    ///The cross reference type used for the current heap.
256 246
    typedef typename TR::HeapCrossRef HeapCrossRef;
257 247
    ///The heap type used by the algorithm.
258 248
    typedef typename TR::Heap Heap;
259 249
    ///The operation traits class.
260 250
    typedef typename TR::OperationTraits OperationTraits;
261 251

	
262 252
    ///The traits class.
263 253
    typedef TR Traits;
264 254

	
265 255
  private:
266 256

	
267 257
    typedef typename Digraph::Node Node;
268 258
    typedef typename Digraph::NodeIt NodeIt;
269 259
    typedef typename Digraph::Arc Arc;
270 260
    typedef typename Digraph::OutArcIt OutArcIt;
271 261

	
272 262
    //Pointer to the underlying digraph.
273 263
    const Digraph *G;
274 264
    //Pointer to the length map.
275 265
    const LengthMap *length;
276 266
    //Pointer to the map of predecessors arcs.
277 267
    PredMap *_pred;
278 268
    //Indicates if _pred is locally allocated (true) or not.
279 269
    bool local_pred;
280 270
    //Pointer to the map of distances.
281 271
    DistMap *_dist;
282 272
    //Indicates if _dist is locally allocated (true) or not.
283 273
    bool local_dist;
284 274
    //Pointer to the map of processed status of the nodes.
285 275
    ProcessedMap *_processed;
286 276
    //Indicates if _processed is locally allocated (true) or not.
287 277
    bool local_processed;
288 278
    //Pointer to the heap cross references.
289 279
    HeapCrossRef *_heap_cross_ref;
290 280
    //Indicates if _heap_cross_ref is locally allocated (true) or not.
291 281
    bool local_heap_cross_ref;
292 282
    //Pointer to the heap.
293 283
    Heap *_heap;
294 284
    //Indicates if _heap is locally allocated (true) or not.
295 285
    bool local_heap;
296 286

	
297 287
    //Creates the maps if necessary.
298 288
    void create_maps()
299 289
    {
300 290
      if(!_pred) {
301 291
        local_pred = true;
302 292
        _pred = Traits::createPredMap(*G);
303 293
      }
304 294
      if(!_dist) {
305 295
        local_dist = true;
306 296
        _dist = Traits::createDistMap(*G);
307 297
      }
308 298
      if(!_processed) {
309 299
        local_processed = true;
310 300
        _processed = Traits::createProcessedMap(*G);
311 301
      }
312 302
      if (!_heap_cross_ref) {
313 303
        local_heap_cross_ref = true;
314 304
        _heap_cross_ref = Traits::createHeapCrossRef(*G);
315 305
      }
316 306
      if (!_heap) {
317 307
        local_heap = true;
318 308
        _heap = Traits::createHeap(*_heap_cross_ref);
319 309
      }
320 310
    }
321 311

	
322 312
  public:
323 313

	
324 314
    typedef Dijkstra Create;
325 315

	
326 316
    ///\name Named template parameters
327 317

	
328 318
    ///@{
329 319

	
330 320
    template <class T>
331 321
    struct SetPredMapTraits : public Traits {
332 322
      typedef T PredMap;
333 323
      static PredMap *createPredMap(const Digraph &)
334 324
      {
335
        throw UninitializedParameter();
325
        LEMON_ASSERT(false, "PredMap is not initialized");
326
        return 0; // ignore warnings
336 327
      }
337 328
    };
338 329
    ///\brief \ref named-templ-param "Named parameter" for setting
339 330
    ///\ref PredMap type.
340 331
    ///
341 332
    ///\ref named-templ-param "Named parameter" for setting
342 333
    ///\ref PredMap type.
343 334
    template <class T>
344 335
    struct SetPredMap
345 336
      : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
346 337
      typedef Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > Create;
347 338
    };
348 339

	
349 340
    template <class T>
350 341
    struct SetDistMapTraits : public Traits {
351 342
      typedef T DistMap;
352 343
      static DistMap *createDistMap(const Digraph &)
353 344
      {
354
        throw UninitializedParameter();
345
        LEMON_ASSERT(false, "DistMap is not initialized");
346
        return 0; // ignore warnings
355 347
      }
356 348
    };
357 349
    ///\brief \ref named-templ-param "Named parameter" for setting
358 350
    ///\ref DistMap type.
359 351
    ///
360 352
    ///\ref named-templ-param "Named parameter" for setting
361 353
    ///\ref DistMap type.
362 354
    template <class T>
363 355
    struct SetDistMap
364 356
      : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
365 357
      typedef Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > Create;
366 358
    };
367 359

	
368 360
    template <class T>
369 361
    struct SetProcessedMapTraits : public Traits {
370 362
      typedef T ProcessedMap;
371 363
      static ProcessedMap *createProcessedMap(const Digraph &)
372 364
      {
373
        throw UninitializedParameter();
365
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
366
        return 0; // ignore warnings
374 367
      }
375 368
    };
376 369
    ///\brief \ref named-templ-param "Named parameter" for setting
377 370
    ///\ref ProcessedMap type.
378 371
    ///
379 372
    ///\ref named-templ-param "Named parameter" for setting
380 373
    ///\ref ProcessedMap type.
381 374
    template <class T>
382 375
    struct SetProcessedMap
383 376
      : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
384 377
      typedef Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > Create;
385 378
    };
386 379

	
387 380
    struct SetStandardProcessedMapTraits : public Traits {
388 381
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
389 382
      static ProcessedMap *createProcessedMap(const Digraph &g)
390 383
      {
391 384
        return new ProcessedMap(g);
392 385
      }
393 386
    };
394 387
    ///\brief \ref named-templ-param "Named parameter" for setting
395 388
    ///\ref ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
396 389
    ///
397 390
    ///\ref named-templ-param "Named parameter" for setting
398 391
    ///\ref ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
399 392
    ///If you don't set it explicitly, it will be automatically allocated.
400 393
    struct SetStandardProcessedMap
401 394
      : public Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits > {
402 395
      typedef Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits >
403 396
      Create;
404 397
    };
405 398

	
406 399
    template <class H, class CR>
407 400
    struct SetHeapTraits : public Traits {
408 401
      typedef CR HeapCrossRef;
409 402
      typedef H Heap;
410 403
      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
411
        throw UninitializedParameter();
404
        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
405
        return 0; // ignore warnings
412 406
      }
413 407
      static Heap *createHeap(HeapCrossRef &)
414 408
      {
415
        throw UninitializedParameter();
409
        LEMON_ASSERT(false, "Heap is not initialized");
410
        return 0; // ignore warnings
416 411
      }
417 412
    };
418 413
    ///\brief \ref named-templ-param "Named parameter" for setting
419 414
    ///heap and cross reference type
420 415
    ///
421 416
    ///\ref named-templ-param "Named parameter" for setting heap and cross
422 417
    ///reference type.
423 418
    template <class H, class CR = typename Digraph::template NodeMap<int> >
424 419
    struct SetHeap
425 420
      : public Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > {
426 421
      typedef Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > Create;
427 422
    };
428 423

	
429 424
    template <class H, class CR>
430 425
    struct SetStandardHeapTraits : public Traits {
431 426
      typedef CR HeapCrossRef;
432 427
      typedef H Heap;
433 428
      static HeapCrossRef *createHeapCrossRef(const Digraph &G) {
434 429
        return new HeapCrossRef(G);
435 430
      }
436 431
      static Heap *createHeap(HeapCrossRef &R)
437 432
      {
438 433
        return new Heap(R);
439 434
      }
440 435
    };
441 436
    ///\brief \ref named-templ-param "Named parameter" for setting
442 437
    ///heap and cross reference type with automatic allocation
443 438
    ///
444 439
    ///\ref named-templ-param "Named parameter" for setting heap and cross
445 440
    ///reference type. It can allocate the heap and the cross reference
446 441
    ///object if the cross reference's constructor waits for the digraph as
447 442
    ///parameter and the heap's constructor waits for the cross reference.
448 443
    template <class H, class CR = typename Digraph::template NodeMap<int> >
449 444
    struct SetStandardHeap
450 445
      : public Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> > {
451 446
      typedef Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> >
452 447
      Create;
453 448
    };
454 449

	
455 450
    template <class T>
456 451
    struct SetOperationTraitsTraits : public Traits {
457 452
      typedef T OperationTraits;
458 453
    };
459 454

	
460 455
    /// \brief \ref named-templ-param "Named parameter" for setting
461 456
    ///\ref OperationTraits type
462 457
    ///
463 458
    ///\ref named-templ-param "Named parameter" for setting
464 459
    ///\ref OperationTraits type.
465 460
    template <class T>
466 461
    struct SetOperationTraits
467 462
      : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
468 463
      typedef Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> >
469 464
      Create;
470 465
    };
471 466

	
472 467
    ///@}
473 468

	
474 469
  protected:
475 470

	
476 471
    Dijkstra() {}
477 472

	
478 473
  public:
479 474

	
480 475
    ///Constructor.
481 476

	
482 477
    ///Constructor.
483 478
    ///\param _g The digraph the algorithm runs on.
484 479
    ///\param _length The length map used by the algorithm.
485 480
    Dijkstra(const Digraph& _g, const LengthMap& _length) :
486 481
      G(&_g), length(&_length),
487 482
      _pred(NULL), local_pred(false),
488 483
      _dist(NULL), local_dist(false),
489 484
      _processed(NULL), local_processed(false),
490 485
      _heap_cross_ref(NULL), local_heap_cross_ref(false),
491 486
      _heap(NULL), local_heap(false)
492 487
    { }
493 488

	
494 489
    ///Destructor.
495 490
    ~Dijkstra()
496 491
    {
497 492
      if(local_pred) delete _pred;
498 493
      if(local_dist) delete _dist;
499 494
      if(local_processed) delete _processed;
500 495
      if(local_heap_cross_ref) delete _heap_cross_ref;
501 496
      if(local_heap) delete _heap;
502 497
    }
503 498

	
504 499
    ///Sets the length map.
505 500

	
506 501
    ///Sets the length map.
507 502
    ///\return <tt> (*this) </tt>
508 503
    Dijkstra &lengthMap(const LengthMap &m)
509 504
    {
510 505
      length = &m;
511 506
      return *this;
512 507
    }
513 508

	
514 509
    ///Sets the map that stores the predecessor arcs.
515 510

	
516 511
    ///Sets the map that stores the predecessor arcs.
517 512
    ///If you don't use this function before calling \ref run(),
518 513
    ///it will allocate one. The destructor deallocates this
519 514
    ///automatically allocated map, of course.
520 515
    ///\return <tt> (*this) </tt>
521 516
    Dijkstra &predMap(PredMap &m)
522 517
    {
523 518
      if(local_pred) {
524 519
        delete _pred;
525 520
        local_pred=false;
526 521
      }
527 522
      _pred = &m;
528 523
      return *this;
529 524
    }
530 525

	
531 526
    ///Sets the map that indicates which nodes are processed.
532 527

	
533 528
    ///Sets the map that indicates which nodes are processed.
534 529
    ///If you don't use this function before calling \ref run(),
535 530
    ///it will allocate one. The destructor deallocates this
536 531
    ///automatically allocated map, of course.
537 532
    ///\return <tt> (*this) </tt>
538 533
    Dijkstra &processedMap(ProcessedMap &m)
539 534
    {
540 535
      if(local_processed) {
541 536
        delete _processed;
542 537
        local_processed=false;
543 538
      }
544 539
      _processed = &m;
545 540
      return *this;
546 541
    }
547 542

	
548 543
    ///Sets the map that stores the distances of the nodes.
549 544

	
550 545
    ///Sets the map that stores the distances of the nodes calculated by the
551 546
    ///algorithm.
552 547
    ///If you don't use this function before calling \ref run(),
553 548
    ///it will allocate one. The destructor deallocates this
554 549
    ///automatically allocated map, of course.
555 550
    ///\return <tt> (*this) </tt>
556 551
    Dijkstra &distMap(DistMap &m)
557 552
    {
558 553
      if(local_dist) {
559 554
        delete _dist;
560 555
        local_dist=false;
561 556
      }
562 557
      _dist = &m;
563 558
      return *this;
564 559
    }
565 560

	
566 561
    ///Sets the heap and the cross reference used by algorithm.
567 562

	
568 563
    ///Sets the heap and the cross reference used by algorithm.
569 564
    ///If you don't use this function before calling \ref run(),
570 565
    ///it will allocate one. The destructor deallocates this
571 566
    ///automatically allocated heap and cross reference, of course.
572 567
    ///\return <tt> (*this) </tt>
573 568
    Dijkstra &heap(Heap& hp, HeapCrossRef &cr)
574 569
    {
575 570
      if(local_heap_cross_ref) {
576 571
        delete _heap_cross_ref;
577 572
        local_heap_cross_ref=false;
578 573
      }
579 574
      _heap_cross_ref = &cr;
580 575
      if(local_heap) {
581 576
        delete _heap;
582 577
        local_heap=false;
583 578
      }
584 579
      _heap = &hp;
585 580
      return *this;
586 581
    }
587 582

	
588 583
  private:
589 584

	
590 585
    void finalizeNodeData(Node v,Value dst)
591 586
    {
592 587
      _processed->set(v,true);
593 588
      _dist->set(v, dst);
594 589
    }
595 590

	
596 591
  public:
597 592

	
598 593
    ///\name Execution control
599 594
    ///The simplest way to execute the algorithm is to use one of the
600 595
    ///member functions called \ref lemon::Dijkstra::run() "run()".
601 596
    ///\n
602 597
    ///If you need more control on the execution, first you must call
603 598
    ///\ref lemon::Dijkstra::init() "init()", then you can add several
604 599
    ///source nodes with \ref lemon::Dijkstra::addSource() "addSource()".
605 600
    ///Finally \ref lemon::Dijkstra::start() "start()" will perform the
606 601
    ///actual path computation.
607 602

	
... ...
@@ -969,345 +964,343 @@
969 964
    ///The heap type used by the Dijkstra algorithm.
970 965

	
971 966
    ///The heap type used by the Dijkstra algorithm.
972 967
    ///
973 968
    ///\sa BinHeap
974 969
    ///\sa Dijkstra
975 970
    typedef BinHeap<Value, typename Digraph::template NodeMap<int>,
976 971
                    std::less<Value> > Heap;
977 972

	
978 973
    ///Instantiates a \ref Heap.
979 974

	
980 975
    ///This function instantiates a \ref Heap.
981 976
    /// \param r is the HeapCrossRef which is used.
982 977
    static Heap *createHeap(HeapCrossRef& r)
983 978
    {
984 979
      return new Heap(r);
985 980
    }
986 981

	
987 982
    ///\brief The type of the map that stores the predecessor
988 983
    ///arcs of the shortest paths.
989 984
    ///
990 985
    ///The type of the map that stores the predecessor
991 986
    ///arcs of the shortest paths.
992 987
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
993 988
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
994 989
    ///Instantiates a \ref PredMap.
995 990

	
996 991
    ///This function instantiates a \ref PredMap.
997 992
    ///\param g is the digraph, to which we would like to define the
998 993
    ///\ref PredMap.
999 994
    static PredMap *createPredMap(const Digraph &g)
1000 995
    {
1001 996
      return new PredMap(g);
1002 997
    }
1003 998

	
1004 999
    ///The type of the map that indicates which nodes are processed.
1005 1000

	
1006 1001
    ///The type of the map that indicates which nodes are processed.
1007 1002
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
1008 1003
    ///By default it is a NullMap.
1009 1004
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
1010 1005
    ///Instantiates a \ref ProcessedMap.
1011 1006

	
1012 1007
    ///This function instantiates a \ref ProcessedMap.
1013 1008
    ///\param g is the digraph, to which
1014 1009
    ///we would like to define the \ref ProcessedMap.
1015 1010
#ifdef DOXYGEN
1016 1011
    static ProcessedMap *createProcessedMap(const Digraph &g)
1017 1012
#else
1018 1013
    static ProcessedMap *createProcessedMap(const Digraph &)
1019 1014
#endif
1020 1015
    {
1021 1016
      return new ProcessedMap();
1022 1017
    }
1023 1018

	
1024 1019
    ///The type of the map that stores the distances of the nodes.
1025 1020

	
1026 1021
    ///The type of the map that stores the distances of the nodes.
1027 1022
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
1028 1023
    typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
1029 1024
    ///Instantiates a \ref DistMap.
1030 1025

	
1031 1026
    ///This function instantiates a \ref DistMap.
1032 1027
    ///\param g is the digraph, to which we would like to define
1033 1028
    ///the \ref DistMap
1034 1029
    static DistMap *createDistMap(const Digraph &g)
1035 1030
    {
1036 1031
      return new DistMap(g);
1037 1032
    }
1038 1033

	
1039 1034
    ///The type of the shortest paths.
1040 1035

	
1041 1036
    ///The type of the shortest paths.
1042 1037
    ///It must meet the \ref concepts::Path "Path" concept.
1043 1038
    typedef lemon::Path<Digraph> Path;
1044 1039
  };
1045 1040

	
1046 1041
  /// Default traits class used by \ref DijkstraWizard
1047 1042

	
1048 1043
  /// To make it easier to use Dijkstra algorithm
1049 1044
  /// we have created a wizard class.
1050 1045
  /// This \ref DijkstraWizard class needs default traits,
1051 1046
  /// as well as the \ref Dijkstra class.
1052 1047
  /// The \ref DijkstraWizardBase is a class to be the default traits of the
1053 1048
  /// \ref DijkstraWizard class.
1054 1049
  template<class GR,class LM>
1055 1050
  class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LM>
1056 1051
  {
1057 1052
    typedef DijkstraWizardDefaultTraits<GR,LM> Base;
1058 1053
  protected:
1059 1054
    //The type of the nodes in the digraph.
1060 1055
    typedef typename Base::Digraph::Node Node;
1061 1056

	
1062 1057
    //Pointer to the digraph the algorithm runs on.
1063 1058
    void *_g;
1064 1059
    //Pointer to the length map.
1065 1060
    void *_length;
1066 1061
    //Pointer to the map of processed nodes.
1067 1062
    void *_processed;
1068 1063
    //Pointer to the map of predecessors arcs.
1069 1064
    void *_pred;
1070 1065
    //Pointer to the map of distances.
1071 1066
    void *_dist;
1072 1067
    //Pointer to the shortest path to the target node.
1073 1068
    void *_path;
1074 1069
    //Pointer to the distance of the target node.
1075 1070
    void *_di;
1076 1071

	
1077 1072
  public:
1078 1073
    /// Constructor.
1079 1074

	
1080 1075
    /// This constructor does not require parameters, therefore it initiates
1081 1076
    /// all of the attributes to \c 0.
1082 1077
    DijkstraWizardBase() : _g(0), _length(0), _processed(0), _pred(0),
1083 1078
                           _dist(0), _path(0), _di(0) {}
1084 1079

	
1085 1080
    /// Constructor.
1086 1081

	
1087 1082
    /// This constructor requires two parameters,
1088 1083
    /// others are initiated to \c 0.
1089 1084
    /// \param g The digraph the algorithm runs on.
1090 1085
    /// \param l The length map.
1091 1086
    DijkstraWizardBase(const GR &g,const LM &l) :
1092 1087
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
1093 1088
      _length(reinterpret_cast<void*>(const_cast<LM*>(&l))),
1094 1089
      _processed(0), _pred(0), _dist(0), _path(0), _di(0) {}
1095 1090

	
1096 1091
  };
1097 1092

	
1098 1093
  /// Auxiliary class for the function-type interface of Dijkstra algorithm.
1099 1094

	
1100 1095
  /// This auxiliary class is created to implement the
1101 1096
  /// \ref dijkstra() "function-type interface" of \ref Dijkstra algorithm.
1102 1097
  /// It does not have own \ref run() method, it uses the functions
1103 1098
  /// and features of the plain \ref Dijkstra.
1104 1099
  ///
1105 1100
  /// This class should only be used through the \ref dijkstra() function,
1106 1101
  /// which makes it easier to use the algorithm.
1107 1102
  template<class TR>
1108 1103
  class DijkstraWizard : public TR
1109 1104
  {
1110 1105
    typedef TR Base;
1111 1106

	
1112 1107
    ///The type of the digraph the algorithm runs on.
1113 1108
    typedef typename TR::Digraph Digraph;
1114 1109

	
1115 1110
    typedef typename Digraph::Node Node;
1116 1111
    typedef typename Digraph::NodeIt NodeIt;
1117 1112
    typedef typename Digraph::Arc Arc;
1118 1113
    typedef typename Digraph::OutArcIt OutArcIt;
1119 1114

	
1120 1115
    ///The type of the map that stores the arc lengths.
1121 1116
    typedef typename TR::LengthMap LengthMap;
1122 1117
    ///The type of the length of the arcs.
1123 1118
    typedef typename LengthMap::Value Value;
1124 1119
    ///\brief The type of the map that stores the predecessor
1125 1120
    ///arcs of the shortest paths.
1126 1121
    typedef typename TR::PredMap PredMap;
1127 1122
    ///The type of the map that stores the distances of the nodes.
1128 1123
    typedef typename TR::DistMap DistMap;
1129 1124
    ///The type of the map that indicates which nodes are processed.
1130 1125
    typedef typename TR::ProcessedMap ProcessedMap;
1131 1126
    ///The type of the shortest paths
1132 1127
    typedef typename TR::Path Path;
1133 1128
    ///The heap type used by the dijkstra algorithm.
1134 1129
    typedef typename TR::Heap Heap;
1135 1130

	
1136 1131
  public:
1137 1132

	
1138 1133
    /// Constructor.
1139 1134
    DijkstraWizard() : TR() {}
1140 1135

	
1141 1136
    /// Constructor that requires parameters.
1142 1137

	
1143 1138
    /// Constructor that requires parameters.
1144 1139
    /// These parameters will be the default values for the traits class.
1145 1140
    /// \param g The digraph the algorithm runs on.
1146 1141
    /// \param l The length map.
1147 1142
    DijkstraWizard(const Digraph &g, const LengthMap &l) :
1148 1143
      TR(g,l) {}
1149 1144

	
1150 1145
    ///Copy constructor
1151 1146
    DijkstraWizard(const TR &b) : TR(b) {}
1152 1147

	
1153 1148
    ~DijkstraWizard() {}
1154 1149

	
1155 1150
    ///Runs Dijkstra algorithm from the given source node.
1156 1151

	
1157 1152
    ///This method runs %Dijkstra algorithm from the given source node
1158 1153
    ///in order to compute the shortest path to each node.
1159 1154
    void run(Node s)
1160 1155
    {
1161
      if (s==INVALID) throw UninitializedParameter();
1162 1156
      Dijkstra<Digraph,LengthMap,TR>
1163 1157
        dijk(*reinterpret_cast<const Digraph*>(Base::_g),
1164 1158
             *reinterpret_cast<const LengthMap*>(Base::_length));
1165 1159
      if (Base::_pred)
1166 1160
        dijk.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1167 1161
      if (Base::_dist)
1168 1162
        dijk.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1169 1163
      if (Base::_processed)
1170 1164
        dijk.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1171 1165
      dijk.run(s);
1172 1166
    }
1173 1167

	
1174 1168
    ///Finds the shortest path between \c s and \c t.
1175 1169

	
1176 1170
    ///This method runs the %Dijkstra algorithm from node \c s
1177 1171
    ///in order to compute the shortest path to node \c t
1178 1172
    ///(it stops searching when \c t is processed).
1179 1173
    ///
1180 1174
    ///\return \c true if \c t is reachable form \c s.
1181 1175
    bool run(Node s, Node t)
1182 1176
    {
1183
      if (s==INVALID || t==INVALID) throw UninitializedParameter();
1184 1177
      Dijkstra<Digraph,LengthMap,TR>
1185 1178
        dijk(*reinterpret_cast<const Digraph*>(Base::_g),
1186 1179
             *reinterpret_cast<const LengthMap*>(Base::_length));
1187 1180
      if (Base::_pred)
1188 1181
        dijk.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1189 1182
      if (Base::_dist)
1190 1183
        dijk.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1191 1184
      if (Base::_processed)
1192 1185
        dijk.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1193 1186
      dijk.run(s,t);
1194 1187
      if (Base::_path)
1195 1188
        *reinterpret_cast<Path*>(Base::_path) = dijk.path(t);
1196 1189
      if (Base::_di)
1197 1190
        *reinterpret_cast<Value*>(Base::_di) = dijk.dist(t);
1198 1191
      return dijk.reached(t);
1199 1192
    }
1200 1193

	
1201 1194
    template<class T>
1202 1195
    struct SetPredMapBase : public Base {
1203 1196
      typedef T PredMap;
1204 1197
      static PredMap *createPredMap(const Digraph &) { return 0; };
1205 1198
      SetPredMapBase(const TR &b) : TR(b) {}
1206 1199
    };
1207 1200
    ///\brief \ref named-func-param "Named parameter"
1208 1201
    ///for setting \ref PredMap object.
1209 1202
    ///
1210 1203
    ///\ref named-func-param "Named parameter"
1211 1204
    ///for setting \ref PredMap object.
1212 1205
    template<class T>
1213 1206
    DijkstraWizard<SetPredMapBase<T> > predMap(const T &t)
1214 1207
    {
1215 1208
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1216 1209
      return DijkstraWizard<SetPredMapBase<T> >(*this);
1217 1210
    }
1218 1211

	
1219 1212
    template<class T>
1220 1213
    struct SetDistMapBase : public Base {
1221 1214
      typedef T DistMap;
1222 1215
      static DistMap *createDistMap(const Digraph &) { return 0; };
1223 1216
      SetDistMapBase(const TR &b) : TR(b) {}
1224 1217
    };
1225 1218
    ///\brief \ref named-func-param "Named parameter"
1226 1219
    ///for setting \ref DistMap object.
1227 1220
    ///
1228 1221
    ///\ref named-func-param "Named parameter"
1229 1222
    ///for setting \ref DistMap object.
1230 1223
    template<class T>
1231 1224
    DijkstraWizard<SetDistMapBase<T> > distMap(const T &t)
1232 1225
    {
1233 1226
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1234 1227
      return DijkstraWizard<SetDistMapBase<T> >(*this);
1235 1228
    }
1236 1229

	
1237 1230
    template<class T>
1238 1231
    struct SetProcessedMapBase : public Base {
1239 1232
      typedef T ProcessedMap;
1240 1233
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1241 1234
      SetProcessedMapBase(const TR &b) : TR(b) {}
1242 1235
    };
1243 1236
    ///\brief \ref named-func-param "Named parameter"
1244 1237
    ///for setting \ref ProcessedMap object.
1245 1238
    ///
1246 1239
    /// \ref named-func-param "Named parameter"
1247 1240
    ///for setting \ref ProcessedMap object.
1248 1241
    template<class T>
1249 1242
    DijkstraWizard<SetProcessedMapBase<T> > processedMap(const T &t)
1250 1243
    {
1251 1244
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1252 1245
      return DijkstraWizard<SetProcessedMapBase<T> >(*this);
1253 1246
    }
1254 1247

	
1255 1248
    template<class T>
1256 1249
    struct SetPathBase : public Base {
1257 1250
      typedef T Path;
1258 1251
      SetPathBase(const TR &b) : TR(b) {}
1259 1252
    };
1260 1253
    ///\brief \ref named-func-param "Named parameter"
1261 1254
    ///for getting the shortest path to the target node.
1262 1255
    ///
1263 1256
    ///\ref named-func-param "Named parameter"
1264 1257
    ///for getting the shortest path to the target node.
1265 1258
    template<class T>
1266 1259
    DijkstraWizard<SetPathBase<T> > path(const T &t)
1267 1260
    {
1268 1261
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1269 1262
      return DijkstraWizard<SetPathBase<T> >(*this);
1270 1263
    }
1271 1264

	
1272 1265
    ///\brief \ref named-func-param "Named parameter"
1273 1266
    ///for getting the distance of the target node.
1274 1267
    ///
1275 1268
    ///\ref named-func-param "Named parameter"
1276 1269
    ///for getting the distance of the target node.
1277 1270
    DijkstraWizard dist(const Value &d)
1278 1271
    {
1279 1272
      Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
1280 1273
      return *this;
1281 1274
    }
1282 1275

	
1283 1276
  };
1284 1277

	
1285 1278
  ///Function-type interface for Dijkstra algorithm.
1286 1279

	
1287 1280
  /// \ingroup shortest_path
1288 1281
  ///Function-type interface for Dijkstra algorithm.
1289 1282
  ///
1290 1283
  ///This function also has several \ref named-func-param "named parameters",
1291 1284
  ///they are declared as the members of class \ref DijkstraWizard.
1292 1285
  ///The following examples show how to use these parameters.
1293 1286
  ///\code
1294 1287
  ///  // Compute shortest path from node s to each node
1295 1288
  ///  dijkstra(g,length).predMap(preds).distMap(dists).run(s);
1296 1289
  ///
1297 1290
  ///  // Compute shortest path from s to t
1298 1291
  ///  bool reached = dijkstra(g,length).path(p).dist(d).run(s,t);
1299 1292
  ///\endcode
1300 1293
  ///\warning Don't forget to put the \ref DijkstraWizard::run() "run()"
1301 1294
  ///to the end of the parameter list.
1302 1295
  ///\sa DijkstraWizard
1303 1296
  ///\sa Dijkstra
1304 1297
  template<class GR, class LM>
1305 1298
  DijkstraWizard<DijkstraWizardBase<GR,LM> >
1306 1299
  dijkstra(const GR &digraph, const LM &length)
1307 1300
  {
1308 1301
    return DijkstraWizard<DijkstraWizardBase<GR,LM> >(digraph,length);
1309 1302
  }
1310 1303

	
1311 1304
} //END OF NAMESPACE LEMON
1312 1305

	
1313 1306
#endif
Ignore white space 384 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_ERROR_H
20 20
#define LEMON_ERROR_H
21 21

	
22 22
/// \ingroup exceptions
23 23
/// \file
24 24
/// \brief Basic exception classes and error handling.
25 25

	
26 26
#include <exception>
27 27
#include <string>
28 28
#include <sstream>
29 29
#include <iostream>
30 30
#include <cstdlib>
31 31
#include <memory>
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  /// \addtogroup exceptions
36 36
  /// @{
37 37

	
38
  /// \brief Exception safe wrapper class.
38
  /// \brief Generic exception class.
39 39
  ///
40
  /// Exception safe wrapper class to implement the members of exceptions.
41
  template <typename _Type>
42
  class ExceptionMember {
43
  public:
44
    typedef _Type Type;
45

	
46
    ExceptionMember() throw() {
47
      try {
48
        ptr.reset(new Type());
49
      } catch (...) {}
50
    }
51

	
52
    ExceptionMember(const Type& type) throw() {
53
      try {
54
        ptr.reset(new Type());
55
        if (ptr.get() == 0) return;
56
        *ptr = type;
57
      } catch (...) {}
58
    }
59

	
60
    ExceptionMember(const ExceptionMember& copy) throw() {
61
      try {
62
        if (!copy.valid()) return;
63
        ptr.reset(new Type());
64
        if (ptr.get() == 0) return;
65
        *ptr = copy.get();
66
      } catch (...) {}
67
    }
68

	
69
    ExceptionMember& operator=(const ExceptionMember& copy) throw() {
70
      if (ptr.get() == 0) return;
71
      try {
72
        if (!copy.valid()) return;
73
        *ptr = copy.get();
74
      } catch (...) {}
75
    }
76

	
77
    void set(const Type& type) throw() {
78
      if (ptr.get() == 0) return;
79
      try {
80
        *ptr = type;
81
      } catch (...) {}
82
    }
83

	
84
    const Type& get() const {
85
      return *ptr;
86
    }
87

	
88
    bool valid() const throw() {
89
      return ptr.get() != 0;
90
    }
91

	
92
  private:
93
    std::auto_ptr<_Type> ptr;
94
  };
95

	
96
  /// Exception-safe convenient error message builder class.
97

	
98
  /// Helper class which provides a convenient ostream-like (operator <<
99
  /// based) interface to create a string message. Mostly useful in
100
  /// exception classes (therefore the name).
101
  class ErrorMessage {
102
  protected:
103
    ///\e
104

	
105
    mutable std::auto_ptr<std::ostringstream> buf;
106

	
107
    ///\e
108
    bool init() throw() {
109
      try {
110
        buf.reset(new std::ostringstream);
111
      }
112
      catch(...) {
113
        buf.reset();
114
      }
115
      return buf.get();
116
    }
117

	
118
  public:
119

	
120
    ///\e
121
    ErrorMessage() throw() { init(); }
122

	
123
    ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
124

	
125
    ///\e
126
    ErrorMessage(const char *msg) throw() {
127
      init();
128
      *this << msg;
129
    }
130

	
131
    ///\e
132
    ErrorMessage(const std::string &msg) throw() {
133
      init();
134
      *this << msg;
135
    }
136

	
137
    ///\e
138
    template <typename T>
139
    ErrorMessage& operator<<(const T &t) throw() {
140
      if( ! buf.get() ) return *this;
141

	
142
      try {
143
        *buf << t;
144
      }
145
      catch(...) {
146
        buf.reset();
147
      }
148
      return *this;
149
    }
150

	
151
    ///\e
152
    const char* message() throw() {
153
      if( ! buf.get() ) return 0;
154

	
155
      const char* mes = 0;
156
      try {
157
        mes = buf->str().c_str();
158
      }
159
      catch(...) {}
160
      return mes;
161
    }
162

	
163
  };
164

	
165
  /// Generic exception class.
166

	
167 40
  /// Base class for exceptions used in LEMON.
168 41
  ///
169 42
  class Exception : public std::exception {
170 43
  public:
171
    ///\e
44
    ///\e Constructor
172 45
    Exception() {}
173
    ///\e
46
    ///\e Virtual destructor
174 47
    virtual ~Exception() throw() {}
175
    ///\e
48
    ///\e A short description of the exception
176 49
    virtual const char* what() const throw() {
177 50
      return "lemon::Exception";
178 51
    }
179 52
  };
180 53

	
181
  /// One of the two main subclasses of \ref Exception.
54
  /// \brief Input-Output error
55
  ///
56
  /// This exception is thrown when a file operation cannot be
57
  /// succeeded.
58
  class IoError : public Exception {
59
  protected:
60
    std::string _message;
61
    std::string _file;
182 62

	
183
  /// Logic errors represent problems in the internal logic of a program;
184
  /// in theory, these are preventable, and even detectable before the
185
  /// program runs (e.g. violations of class invariants).
186
  ///
187
  /// A typical example for this is \ref UninitializedParameter.
188
  class LogicError : public Exception {
63
    mutable std::string _what;
189 64
  public:
65

	
66
    /// Copy constructor
67
    IoError(const IoError &error) {
68
      message(error._message);
69
      file(error._file);
70
    }
71

	
72
    /// Constructor
73
    explicit IoError(const char *message) {
74
      IoError::message(message);
75
    }
76

	
77
    /// Constructor
78
    explicit IoError(const std::string &message) {
79
      IoError::message(message);
80
    }
81

	
82
    /// Constructor
83
    IoError(const std::string &file, const char *message) {
84
      IoError::message(message);
85
      IoError::file(file);
86
    }
87

	
88
    /// Constructor
89
    IoError(const std::string &file, const std::string &message) {
90
      IoError::message(message);
91
      IoError::file(file);
92
    }
93

	
94
    /// Virtual destructor
95
    virtual ~IoError() throw() {}
96

	
97
    /// Set the error message
98
    void message(const char *message) {
99
      try {
100
        _message = message;
101
      } catch (...) {}
102
    }
103

	
104
    /// Set the error message
105
    void message(const std::string& message) {
106
      try {
107
        _message = message;
108
      } catch (...) {}
109
    }
110

	
111
    /// Set the file name
112
    void file(const std::string &file) {
113
      try {
114
        _file = file;
115
      } catch (...) {}
116
    }
117

	
118
    /// Returns the error message
119
    const std::string& message() const {
120
      return _message;
121
    }
122

	
123
    /// \brief Returns the filename
124
    ///
125
    /// Returns the filename or empty string if the filename was not
126
    /// specified.
127
    const std::string& file() const {
128
      return _file;
129
    }
130

	
131
    /// \brief Returns a short error message
132
    ///
133
    /// Returns a short error message which contains the message, the
134
    /// file name and the line number.
190 135
    virtual const char* what() const throw() {
191
      return "lemon::LogicError";
136
      try {
137
        _what.clear();
138
        std::ostringstream oss;
139
        oss << "lemon:IoError" << ": ";
140
        oss << message();
141
        if (!file().empty()) {
142
          oss << " (";
143
          if (!file().empty()) oss << "with file '" << file() << "'";
144
          oss << ")";
145
        }
146
        _what = oss.str();
147
      }
148
      catch (...) {}
149
      if (!_what.empty()) return _what.c_str();
150
      else return "lemon:IoError";
192 151
    }
152

	
193 153
  };
194 154

	
195
  /// \ref Exception for uninitialized parameters.
196

	
197
  /// This error represents problems in the initialization
198
  /// of the parameters of the algorithms.
199
  class UninitializedParameter : public LogicError {
200
  public:
201
    virtual const char* what() const throw() {
202
      return "lemon::UninitializedParameter";
203
    }
204
  };
205

	
206

	
207
  /// One of the two main subclasses of \ref Exception.
208

	
209
  /// Runtime errors represent problems outside the scope of a program;
210
  /// they cannot be easily predicted and can generally only be caught
211
  /// as the program executes.
212
  class RuntimeError : public Exception {
213
  public:
214
    virtual const char* what() const throw() {
215
      return "lemon::RuntimeError";
216
    }
217
  };
218

	
219
  ///\e
220
  class RangeError : public RuntimeError {
221
  public:
222
    virtual const char* what() const throw() {
223
      return "lemon::RangeError";
224
    }
225
  };
226

	
227
  ///\e
228
  class IoError : public RuntimeError {
229
  public:
230
    virtual const char* what() const throw() {
231
      return "lemon::IoError";
232
    }
233
  };
234

	
235
  ///\e
236
  class DataFormatError : public IoError {
155
  /// \brief Format error
156
  ///
157
  /// This class is used to indicate if an input file has wrong
158
  /// formatting, or a data representation is not legal.
159
  class FormatError : public Exception {
237 160
  protected:
238
    ExceptionMember<std::string> _message;
239
    ExceptionMember<std::string> _file;
161
    std::string _message;
162
    std::string _file;
240 163
    int _line;
241 164

	
242
    mutable ExceptionMember<std::string> _message_holder;
165
    mutable std::string _what;
243 166
  public:
244 167

	
245
    DataFormatError(const DataFormatError &dfe) :
246
      IoError(dfe), _message(dfe._message), _file(dfe._file),
247
      _line(dfe._line) {}
248

	
249
    ///\e
250
    explicit DataFormatError(const char *the_message)
251
      : _message(the_message), _line(0) {}
252

	
253
    ///\e
254
    DataFormatError(const std::string &file_name, int line_num,
255
                    const char *the_message)
256
      : _message(the_message), _line(line_num) { file(file_name); }
257

	
258
    ///\e
259
    void line(int ln) { _line = ln; }
260
    ///\e
261
    void message(const std::string& msg) { _message.set(msg); }
262
    ///\e
263
    void file(const std::string &fl) { _file.set(fl); }
264

	
265
    ///\e
266
    int line() const { return _line; }
267
    ///\e
268
    const char* message() const {
269
      if (_message.valid() && !_message.get().empty()) {
270
        return _message.get().c_str();
271
      } else {
272
        return 0;
273
      }
168
    /// Copy constructor
169
    FormatError(const FormatError &error) {
170
      message(error._message);
171
      file(error._file);
172
      line(error._line);
274 173
    }
275 174

	
276
    /// \brief Returns the filename.
277
    ///
278
    /// Returns \e null if the filename was not specified.
279
    const char* file() const {
280
      if (_file.valid() && !_file.get().empty()) {
281
        return _file.get().c_str();
282
      } else {
283
        return 0;
284
      }
175
    /// Constructor
176
    explicit FormatError(const char *message) {
177
      FormatError::message(message);
178
      _line = 0;
285 179
    }
286 180

	
287
    ///\e
181
    /// Constructor
182
    explicit FormatError(const std::string &message) {
183
      FormatError::message(message);
184
      _line = 0;
185
    }
186

	
187
    /// Constructor
188
    FormatError(const std::string &file, int line, const char *message) {
189
      FormatError::message(message);
190
      FormatError::file(file);
191
      FormatError::line(line);
192
    }
193

	
194
    /// Constructor
195
    FormatError(const std::string &file, int line, const std::string &message) {
196
      FormatError::message(message);
197
      FormatError::file(file);
198
      FormatError::line(line);
199
    }
200

	
201
    /// Virtual destructor
202
    virtual ~FormatError() throw() {}
203

	
204
    /// Set the line number
205
    void line(int line) { _line = line; }
206

	
207
    /// Set the error message
208
    void message(const char *message) {
209
      try {
210
        _message = message;
211
      } catch (...) {}
212
    }
213

	
214
    /// Set the error message
215
    void message(const std::string& message) {
216
      try {
217
        _message = message;
218
      } catch (...) {}
219
    }
220

	
221
    /// Set the file name
222
    void file(const std::string &file) {
223
      try {
224
        _file = file;
225
      } catch (...) {}
226
    }
227

	
228
    /// \brief Returns the line number
229
    ///
230
    /// Returns the line number or zero if it was not specified.
231
    int line() const { return _line; }
232

	
233
    /// Returns the error message
234
    const std::string& message() const {
235
      return _message;
236
    }
237

	
238
    /// \brief Returns the filename
239
    ///
240
    /// Returns the filename or empty string if the filename was not
241
    /// specified.
242
    const std::string& file() const {
243
      return _file;
244
    }
245

	
246
    /// \brief Returns a short error message
247
    ///
248
    /// Returns a short error message which contains the message, the
249
    /// file name and the line number.
288 250
    virtual const char* what() const throw() {
289 251
      try {
290
        std::ostringstream ostr;
291
        ostr << "lemon:DataFormatError" << ": ";
292
        if (message()) ostr << message();
293
        if( file() || line() != 0 ) {
294
          ostr << " (";
295
          if( file() ) ostr << "in file '" << file() << "'";
296
          if( file() && line() != 0 ) ostr << " ";
297
          if( line() != 0 ) ostr << "at line " << line();
298
          ostr << ")";
252
        _what.clear();
253
        std::ostringstream oss;
254
        oss << "lemon:FormatError" << ": ";
255
        oss << message();
256
        if (!file().empty() || line() != 0) {
257
          oss << " (";
258
          if (!file().empty()) oss << "in file '" << file() << "'";
259
          if (!file().empty() && line() != 0) oss << " ";
260
          if (line() != 0) oss << "at line " << line();
261
          oss << ")";
299 262
        }
300
        _message_holder.set(ostr.str());
263
        _what = oss.str();
301 264
      }
302 265
      catch (...) {}
303
      if( _message_holder.valid()) return _message_holder.get().c_str();
304
      return "lemon:DataFormatError";
266
      if (!_what.empty()) return _what.c_str();
267
      else return "lemon:FormatError";
305 268
    }
306 269

	
307
    virtual ~DataFormatError() throw() {}
308
  };
309

	
310
  ///\e
311
  class FileOpenError : public IoError {
312
  protected:
313
    ExceptionMember<std::string> _file;
314

	
315
    mutable ExceptionMember<std::string> _message_holder;
316
  public:
317

	
318
    FileOpenError(const FileOpenError &foe) :
319
      IoError(foe), _file(foe._file) {}
320

	
321
    ///\e
322
    explicit FileOpenError(const std::string& fl)
323
      : _file(fl) {}
324

	
325

	
326
    ///\e
327
    void file(const std::string &fl) { _file.set(fl); }
328

	
329
    /// \brief Returns the filename.
330
    ///
331
    /// Returns \e null if the filename was not specified.
332
    const char* file() const {
333
      if (_file.valid() && !_file.get().empty()) {
334
        return _file.get().c_str();
335
      } else {
336
        return 0;
337
      }
338
    }
339

	
340
    ///\e
341
    virtual const char* what() const throw() {
342
      try {
343
        std::ostringstream ostr;
344
        ostr << "lemon::FileOpenError" << ": ";
345
        ostr << "Cannot open file - " << file();
346
        _message_holder.set(ostr.str());
347
      }
348
      catch (...) {}
349
      if( _message_holder.valid()) return _message_holder.get().c_str();
350
      return "lemon::FileOpenError";
351
    }
352
    virtual ~FileOpenError() throw() {}
353
  };
354

	
355
  class IoParameterError : public IoError {
356
  protected:
357
    ExceptionMember<std::string> _message;
358
    ExceptionMember<std::string> _file;
359

	
360
    mutable ExceptionMember<std::string> _message_holder;
361
  public:
362

	
363
    IoParameterError(const IoParameterError &ile) :
364
      IoError(ile), _message(ile._message), _file(ile._file) {}
365

	
366
    ///\e
367
    explicit IoParameterError(const char *the_message)
368
      : _message(the_message) {}
369

	
370
    ///\e
371
    IoParameterError(const char *file_name, const char *the_message)
372
      : _message(the_message), _file(file_name) {}
373

	
374
     ///\e
375
    void message(const std::string& msg) { _message.set(msg); }
376
    ///\e
377
    void file(const std::string &fl) { _file.set(fl); }
378

	
379
     ///\e
380
    const char* message() const {
381
      if (_message.valid()) {
382
        return _message.get().c_str();
383
      } else {
384
        return 0;
385
      }
386
    }
387

	
388
    /// \brief Returns the filename.
389
    ///
390
    /// Returns \c 0 if the filename was not specified.
391
    const char* file() const {
392
      if (_file.valid()) {
393
        return _file.get().c_str();
394
      } else {
395
        return 0;
396
      }
397
    }
398

	
399
    ///\e
400
    virtual const char* what() const throw() {
401
      try {
402
        std::ostringstream ostr;
403
        if (message()) ostr << message();
404
        if (file()) ostr << "(when reading file '" << file() << "')";
405
        _message_holder.set(ostr.str());
406
      }
407
      catch (...) {}
408
      if( _message_holder.valid() ) return _message_holder.get().c_str();
409
      return "lemon:IoParameterError";
410
    }
411
    virtual ~IoParameterError() throw() {}
412 270
  };
413 271

	
414 272
  /// @}
415 273

	
416 274
}
417 275

	
418 276
#endif // LEMON_ERROR_H
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_GRAPH_TO_EPS_H
20 20
#define LEMON_GRAPH_TO_EPS_H
21 21

	
22 22
#include<iostream>
23 23
#include<fstream>
24 24
#include<sstream>
25 25
#include<algorithm>
26 26
#include<vector>
27 27

	
28 28
#ifndef WIN32
29 29
#include<sys/time.h>
30 30
#include<ctime>
31 31
#else
32 32
#define WIN32_LEAN_AND_MEAN
33 33
#define NOMINMAX
34 34
#include<windows.h>
35 35
#endif
36 36

	
37 37
#include<lemon/math.h>
38 38
#include<lemon/core.h>
39 39
#include<lemon/dim2.h>
40 40
#include<lemon/maps.h>
41 41
#include<lemon/color.h>
42 42
#include<lemon/bits/bezier.h>
43
#include<lemon/error.h>
43 44

	
44 45

	
45 46
///\ingroup eps_io
46 47
///\file
47 48
///\brief A well configurable tool for visualizing graphs
48 49

	
49 50
namespace lemon {
50 51

	
51 52
  namespace _graph_to_eps_bits {
52 53
    template<class MT>
53 54
    class _NegY {
54 55
    public:
55 56
      typedef typename MT::Key Key;
56 57
      typedef typename MT::Value Value;
57 58
      const MT &map;
58 59
      int yscale;
59 60
      _NegY(const MT &m,bool b) : map(m), yscale(1-b*2) {}
60 61
      Value operator[](Key n) { return Value(map[n].x,map[n].y*yscale);}
61 62
    };
62 63
  }
63 64

	
64 65
///Default traits class of \ref GraphToEps
65 66

	
66 67
///Default traits class of \ref GraphToEps.
67 68
///
68 69
///\c G is the type of the underlying graph.
69 70
template<class G>
70 71
struct DefaultGraphToEpsTraits
71 72
{
72 73
  typedef G Graph;
73 74
  typedef typename Graph::Node Node;
74 75
  typedef typename Graph::NodeIt NodeIt;
75 76
  typedef typename Graph::Arc Arc;
76 77
  typedef typename Graph::ArcIt ArcIt;
77 78
  typedef typename Graph::InArcIt InArcIt;
78 79
  typedef typename Graph::OutArcIt OutArcIt;
79 80

	
80 81

	
81 82
  const Graph &g;
82 83

	
83 84
  std::ostream& os;
84 85

	
85 86
  typedef ConstMap<typename Graph::Node,dim2::Point<double> > CoordsMapType;
86 87
  CoordsMapType _coords;
87 88
  ConstMap<typename Graph::Node,double > _nodeSizes;
88 89
  ConstMap<typename Graph::Node,int > _nodeShapes;
89 90

	
90 91
  ConstMap<typename Graph::Node,Color > _nodeColors;
91 92
  ConstMap<typename Graph::Arc,Color > _arcColors;
92 93

	
93 94
  ConstMap<typename Graph::Arc,double > _arcWidths;
94 95

	
95 96
  double _arcWidthScale;
96 97

	
97 98
  double _nodeScale;
98 99
  double _xBorder, _yBorder;
99 100
  double _scale;
100 101
  double _nodeBorderQuotient;
101 102

	
102 103
  bool _drawArrows;
103 104
  double _arrowLength, _arrowWidth;
104 105

	
105 106
  bool _showNodes, _showArcs;
106 107

	
107 108
  bool _enableParallel;
108 109
  double _parArcDist;
109 110

	
110 111
  bool _showNodeText;
111 112
  ConstMap<typename Graph::Node,bool > _nodeTexts;
112 113
  double _nodeTextSize;
113 114

	
114 115
  bool _showNodePsText;
115 116
  ConstMap<typename Graph::Node,bool > _nodePsTexts;
116 117
  char *_nodePsTextsPreamble;
117 118

	
118 119
  bool _undirected;
119 120

	
120 121
  bool _pleaseRemoveOsStream;
121 122

	
122 123
  bool _scaleToA4;
123 124

	
124 125
  std::string _title;
125 126
  std::string _copyright;
126 127

	
127 128
  enum NodeTextColorType
128 129
    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
129 130
  ConstMap<typename Graph::Node,Color > _nodeTextColors;
130 131

	
131 132
  bool _autoNodeScale;
132 133
  bool _autoArcWidthScale;
133 134

	
134 135
  bool _absoluteNodeSizes;
135 136
  bool _absoluteArcWidths;
136 137

	
137 138
  bool _negY;
138 139

	
139 140
  bool _preScale;
140 141
  ///Constructor
141 142

	
142 143
  ///Constructor
143 144
  ///\param _g  Reference to the graph to be printed.
144 145
  ///\param _os Reference to the output stream.
145 146
  ///\param _os Reference to the output stream.
146 147
  ///By default it is <tt>std::cout</tt>.
147 148
  ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
148 149
  ///will be explicitly deallocated by the destructor.
149 150
  DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
150 151
                          bool _pros=false) :
151 152
    g(_g), os(_os),
152 153
    _coords(dim2::Point<double>(1,1)), _nodeSizes(1), _nodeShapes(0),
153 154
    _nodeColors(WHITE), _arcColors(BLACK),
154 155
    _arcWidths(1.0), _arcWidthScale(0.003),
155 156
    _nodeScale(.01), _xBorder(10), _yBorder(10), _scale(1.0),
156 157
    _nodeBorderQuotient(.1),
157 158
    _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
158 159
    _showNodes(true), _showArcs(true),
159 160
    _enableParallel(false), _parArcDist(1),
160 161
    _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
161 162
    _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
162 163
    _undirected(lemon::UndirectedTagIndicator<G>::value),
163 164
    _pleaseRemoveOsStream(_pros), _scaleToA4(false),
164 165
    _nodeTextColorType(SAME_COL), _nodeTextColors(BLACK),
165 166
    _autoNodeScale(false),
166 167
    _autoArcWidthScale(false),
167 168
    _absoluteNodeSizes(false),
168 169
    _absoluteArcWidths(false),
169 170
    _negY(false),
170 171
    _preScale(true)
171 172
  {}
172 173
};
173 174

	
174 175
///Auxiliary class to implement the named parameters of \ref graphToEps()
175 176

	
176 177
///Auxiliary class to implement the named parameters of \ref graphToEps().
177 178
///
178 179
///For detailed examples see the \ref graph_to_eps_demo.cc demo file.
179 180
template<class T> class GraphToEps : public T
180 181
{
181 182
  // Can't believe it is required by the C++ standard
182 183
  using T::g;
183 184
  using T::os;
184 185

	
185 186
  using T::_coords;
186 187
  using T::_nodeSizes;
187 188
  using T::_nodeShapes;
188 189
  using T::_nodeColors;
189 190
  using T::_arcColors;
190 191
  using T::_arcWidths;
191 192

	
192 193
  using T::_arcWidthScale;
193 194
  using T::_nodeScale;
194 195
  using T::_xBorder;
195 196
  using T::_yBorder;
196 197
  using T::_scale;
197 198
  using T::_nodeBorderQuotient;
198 199

	
199 200
  using T::_drawArrows;
200 201
  using T::_arrowLength;
201 202
  using T::_arrowWidth;
202 203

	
203 204
  using T::_showNodes;
204 205
  using T::_showArcs;
205 206

	
206 207
  using T::_enableParallel;
207 208
  using T::_parArcDist;
208 209

	
209 210
  using T::_showNodeText;
210 211
  using T::_nodeTexts;
211 212
  using T::_nodeTextSize;
212 213

	
213 214
  using T::_showNodePsText;
214 215
  using T::_nodePsTexts;
215 216
  using T::_nodePsTextsPreamble;
216 217

	
217 218
  using T::_undirected;
218 219

	
219 220
  using T::_pleaseRemoveOsStream;
220 221

	
221 222
  using T::_scaleToA4;
222 223

	
223 224
  using T::_title;
224 225
  using T::_copyright;
225 226

	
226 227
  using T::NodeTextColorType;
227 228
  using T::CUST_COL;
228 229
  using T::DIST_COL;
229 230
  using T::DIST_BW;
230 231
  using T::_nodeTextColorType;
231 232
  using T::_nodeTextColors;
232 233

	
233 234
  using T::_autoNodeScale;
234 235
  using T::_autoArcWidthScale;
... ...
@@ -977,215 +978,225 @@
977 978
      }
978 979
      else for(ArcIt e(g);e!=INVALID;++e)
979 980
        if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
980 981
           &&g.source(e)!=g.target(e)) {
981 982
          if(_drawArrows) {
982 983
            dim2::Point<double> d(mycoords[g.target(e)]-mycoords[g.source(e)]);
983 984
            double rn=_nodeSizes[g.target(e)]*_nodeScale;
984 985
            int node_shape=_nodeShapes[g.target(e)];
985 986
            double t1=0,t2=1;
986 987
            for(int i=0;i<INTERPOL_PREC;++i)
987 988
              if(isInsideNode((-(t1+t2)/2)*d,rn,node_shape)) t1=(t1+t2)/2;
988 989
              else t2=(t1+t2)/2;
989 990
            double l=std::sqrt(d.normSquare());
990 991
            d/=l;
991 992

	
992 993
            os << l*(1-(t1+t2)/2) << ' '
993 994
               << _arcWidths[e]*_arcWidthScale << ' '
994 995
               << d.x << ' ' << d.y << ' '
995 996
               << mycoords[g.source(e)].x << ' '
996 997
               << mycoords[g.source(e)].y << ' '
997 998
               << _arcColors[e].red() << ' '
998 999
               << _arcColors[e].green() << ' '
999 1000
               << _arcColors[e].blue() << " arr\n";
1000 1001
          }
1001 1002
          else os << mycoords[g.source(e)].x << ' '
1002 1003
                  << mycoords[g.source(e)].y << ' '
1003 1004
                  << mycoords[g.target(e)].x << ' '
1004 1005
                  << mycoords[g.target(e)].y << ' '
1005 1006
                  << _arcColors[e].red() << ' '
1006 1007
                  << _arcColors[e].green() << ' '
1007 1008
                  << _arcColors[e].blue() << ' '
1008 1009
                  << _arcWidths[e]*_arcWidthScale << " l\n";
1009 1010
        }
1010 1011
      os << "grestore\n";
1011 1012
    }
1012 1013
    if(_showNodes) {
1013 1014
      os << "%Nodes:\ngsave\n";
1014 1015
      for(NodeIt n(g);n!=INVALID;++n) {
1015 1016
        os << mycoords[n].x << ' ' << mycoords[n].y << ' '
1016 1017
           << _nodeSizes[n]*_nodeScale << ' '
1017 1018
           << _nodeColors[n].red() << ' '
1018 1019
           << _nodeColors[n].green() << ' '
1019 1020
           << _nodeColors[n].blue() << ' ';
1020 1021
        switch(_nodeShapes[n]) {
1021 1022
        case CIRCLE:
1022 1023
          os<< "nc";break;
1023 1024
        case SQUARE:
1024 1025
          os<< "nsq";break;
1025 1026
        case DIAMOND:
1026 1027
          os<< "ndi";break;
1027 1028
        case MALE:
1028 1029
          os<< "nmale";break;
1029 1030
        case FEMALE:
1030 1031
          os<< "nfemale";break;
1031 1032
        }
1032 1033
        os<<'\n';
1033 1034
      }
1034 1035
      os << "grestore\n";
1035 1036
    }
1036 1037
    if(_showNodeText) {
1037 1038
      os << "%Node texts:\ngsave\n";
1038 1039
      os << "/fosi " << _nodeTextSize << " def\n";
1039 1040
      os << "(Helvetica) findfont fosi scalefont setfont\n";
1040 1041
      for(NodeIt n(g);n!=INVALID;++n) {
1041 1042
        switch(_nodeTextColorType) {
1042 1043
        case DIST_COL:
1043 1044
          os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
1044 1045
          break;
1045 1046
        case DIST_BW:
1046 1047
          os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
1047 1048
          break;
1048 1049
        case CUST_COL:
1049 1050
          os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
1050 1051
          break;
1051 1052
        default:
1052 1053
          os << "0 0 0 setrgbcolor\n";
1053 1054
        }
1054 1055
        os << mycoords[n].x << ' ' << mycoords[n].y
1055 1056
           << " (" << _nodeTexts[n] << ") cshow\n";
1056 1057
      }
1057 1058
      os << "grestore\n";
1058 1059
    }
1059 1060
    if(_showNodePsText) {
1060 1061
      os << "%Node PS blocks:\ngsave\n";
1061 1062
      for(NodeIt n(g);n!=INVALID;++n)
1062 1063
        os << mycoords[n].x << ' ' << mycoords[n].y
1063 1064
           << " moveto\n" << _nodePsTexts[n] << "\n";
1064 1065
      os << "grestore\n";
1065 1066
    }
1066 1067

	
1067 1068
    os << "grestore\nshowpage\n";
1068 1069

	
1069 1070
    //CleanUp:
1070 1071
    if(_pleaseRemoveOsStream) {delete &os;}
1071 1072
  }
1072 1073

	
1073 1074
  ///\name Aliases
1074 1075
  ///These are just some aliases to other parameter setting functions.
1075 1076

	
1076 1077
  ///@{
1077 1078

	
1078 1079
  ///An alias for arcWidths()
1079 1080
  template<class X> GraphToEps<ArcWidthsTraits<X> > edgeWidths(const X &x)
1080 1081
  {
1081 1082
    return arcWidths(x);
1082 1083
  }
1083 1084

	
1084 1085
  ///An alias for arcColors()
1085 1086
  template<class X> GraphToEps<ArcColorsTraits<X> >
1086 1087
  edgeColors(const X &x)
1087 1088
  {
1088 1089
    return arcColors(x);
1089 1090
  }
1090 1091

	
1091 1092
  ///An alias for arcWidthScale()
1092 1093
  GraphToEps<T> &edgeWidthScale(double d) {return arcWidthScale(d);}
1093 1094

	
1094 1095
  ///An alias for autoArcWidthScale()
1095 1096
  GraphToEps<T> &autoEdgeWidthScale(bool b=true)
1096 1097
  {
1097 1098
    return autoArcWidthScale(b);
1098 1099
  }
1099 1100

	
1100 1101
  ///An alias for absoluteArcWidths()
1101 1102
  GraphToEps<T> &absoluteEdgeWidths(bool b=true)
1102 1103
  {
1103 1104
    return absoluteArcWidths(b);
1104 1105
  }
1105 1106

	
1106 1107
  ///An alias for parArcDist()
1107 1108
  GraphToEps<T> &parEdgeDist(double d) {return parArcDist(d);}
1108 1109

	
1109 1110
  ///An alias for hideArcs()
1110 1111
  GraphToEps<T> &hideEdges(bool b=true) {return hideArcs(b);}
1111 1112

	
1112 1113
  ///@}
1113 1114
};
1114 1115

	
1115 1116
template<class T>
1116 1117
const int GraphToEps<T>::INTERPOL_PREC = 20;
1117 1118
template<class T>
1118 1119
const double GraphToEps<T>::A4HEIGHT = 841.8897637795276;
1119 1120
template<class T>
1120 1121
const double GraphToEps<T>::A4WIDTH  = 595.275590551181;
1121 1122
template<class T>
1122 1123
const double GraphToEps<T>::A4BORDER = 15;
1123 1124

	
1124 1125

	
1125 1126
///Generates an EPS file from a graph
1126 1127

	
1127 1128
///\ingroup eps_io
1128 1129
///Generates an EPS file from a graph.
1129 1130
///\param g Reference to the graph to be printed.
1130 1131
///\param os Reference to the output stream.
1131 1132
///By default it is <tt>std::cout</tt>.
1132 1133
///
1133 1134
///This function also has a lot of
1134 1135
///\ref named-templ-func-param "named parameters",
1135 1136
///they are declared as the members of class \ref GraphToEps. The following
1136 1137
///example shows how to use these parameters.
1137 1138
///\code
1138 1139
/// graphToEps(g,os).scale(10).coords(coords)
1139 1140
///              .nodeScale(2).nodeSizes(sizes)
1140 1141
///              .arcWidthScale(.4).run();
1141 1142
///\endcode
1142 1143
///
1143 1144
///For more detailed examples see the \ref graph_to_eps_demo.cc demo file.
1144 1145
///
1145 1146
///\warning Don't forget to put the \ref GraphToEps::run() "run()"
1146 1147
///to the end of the parameter list.
1147 1148
///\sa GraphToEps
1148 1149
///\sa graphToEps(G &g, const char *file_name)
1149 1150
template<class G>
1150 1151
GraphToEps<DefaultGraphToEpsTraits<G> >
1151 1152
graphToEps(G &g, std::ostream& os=std::cout)
1152 1153
{
1153 1154
  return
1154 1155
    GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
1155 1156
}
1156 1157

	
1157 1158
///Generates an EPS file from a graph
1158 1159

	
1159 1160
///\ingroup eps_io
1160 1161
///This function does the same as
1161 1162
///\ref graphToEps(G &g,std::ostream& os)
1162 1163
///but it writes its output into the file \c file_name
1163 1164
///instead of a stream.
1164 1165
///\sa graphToEps(G &g, std::ostream& os)
1165 1166
template<class G>
1166 1167
GraphToEps<DefaultGraphToEpsTraits<G> >
1167 1168
graphToEps(G &g,const char *file_name)
1168 1169
{
1170
  std::ostream* os = new std::ofstream(file_name);
1171
  if (!(*os)) {
1172
    delete os;
1173
    throw IoError(file_name, "Cannot write file");
1174
  }
1169 1175
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1170
    (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name),true));
1176
    (DefaultGraphToEpsTraits<G>(g,*os,true));
1171 1177
}
1172 1178

	
1173 1179
///Generates an EPS file from a graph
1174 1180

	
1175 1181
///\ingroup eps_io
1176 1182
///This function does the same as
1177 1183
///\ref graphToEps(G &g,std::ostream& os)
1178 1184
///but it writes its output into the file \c file_name
1179 1185
///instead of a stream.
1180 1186
///\sa graphToEps(G &g, std::ostream& os)
1181 1187
template<class G>
1182 1188
GraphToEps<DefaultGraphToEpsTraits<G> >
1183 1189
graphToEps(G &g,const std::string& file_name)
1184 1190
{
1191
  std::ostream* os = new std::ofstream(file_name.c_str());
1192
  if (!(*os)) {
1193
    delete os;
1194
    throw IoError(file_name, "Cannot write file");
1195
  }
1185 1196
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1186
    (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name.c_str()),true));
1197
    (DefaultGraphToEpsTraits<G>(g,*os,true));
1187 1198
}
1188 1199

	
1189 1200
} //END OF NAMESPACE LEMON
1190 1201

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

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

	
23 23

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

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

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

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

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

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

	
42 42
namespace lemon {
43 43

	
44 44
  namespace _reader_bits {
45 45

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

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

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

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

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

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

	
79 81
    };
80 82

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
331 333
      Functor _functor;
332 334

	
333 335
    public:
334 336

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

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

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

	
363 365
      Functor _functor;
364 366

	
365 367
    public:
366 368

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

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

	
387 389
  }
388 390

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

	
392 394
  template <typename Digraph>
393 395
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph);
394 396

	
395 397
  template <typename Digraph>
396 398
  DigraphReader<Digraph> digraphReader(const std::string& fn, Digraph& digraph);
397 399

	
398 400
  template <typename Digraph>
399 401
  DigraphReader<Digraph> digraphReader(const char *fn, Digraph& digraph);
400 402

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

	
455 457
    typedef _Digraph Digraph;
456 458
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
457 459

	
458 460
  private:
459 461

	
460 462

	
461 463
    std::istream* _is;
462 464
    bool local_is;
465
    std::string _filename;
463 466

	
464 467
    Digraph& _digraph;
465 468

	
466 469
    std::string _nodes_caption;
467 470
    std::string _arcs_caption;
468 471
    std::string _attributes_caption;
469 472

	
470 473
    typedef std::map<std::string, Node> NodeIndex;
471 474
    NodeIndex _node_index;
472 475
    typedef std::map<std::string, Arc> ArcIndex;
473 476
    ArcIndex _arc_index;
474 477

	
475 478
    typedef std::vector<std::pair<std::string,
476 479
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
477 480
    NodeMaps _node_maps;
478 481

	
479 482
    typedef std::vector<std::pair<std::string,
480 483
      _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
481 484
    ArcMaps _arc_maps;
482 485

	
483 486
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
484 487
      Attributes;
485 488
    Attributes _attributes;
486 489

	
487 490
    bool _use_nodes;
488 491
    bool _use_arcs;
489 492

	
490 493
    bool _skip_nodes;
491 494
    bool _skip_arcs;
492 495

	
493 496
    int line_num;
494 497
    std::istringstream line;
495 498

	
496 499
  public:
497 500

	
498 501
    /// \brief Constructor
499 502
    ///
500 503
    /// Construct a directed graph reader, which reads from the given
501 504
    /// input stream.
502 505
    DigraphReader(std::istream& is, Digraph& digraph)
503 506
      : _is(&is), local_is(false), _digraph(digraph),
504 507
        _use_nodes(false), _use_arcs(false),
505 508
        _skip_nodes(false), _skip_arcs(false) {}
506 509

	
507 510
    /// \brief Constructor
508 511
    ///
509 512
    /// Construct a directed graph reader, which reads from the given
510 513
    /// file.
511 514
    DigraphReader(const std::string& fn, Digraph& digraph)
512
      : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
515
      : _is(new std::ifstream(fn.c_str())), local_is(true),
516
        _filename(fn), _digraph(digraph),
513 517
        _use_nodes(false), _use_arcs(false),
514
        _skip_nodes(false), _skip_arcs(false) {}
518
        _skip_nodes(false), _skip_arcs(false) {
519
      if (!(*_is)) throw IoError(fn, "Cannot open file");
520
    }
515 521

	
516 522
    /// \brief Constructor
517 523
    ///
518 524
    /// Construct a directed graph reader, which reads from the given
519 525
    /// file.
520 526
    DigraphReader(const char* fn, Digraph& digraph)
521
      : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
527
      : _is(new std::ifstream(fn)), local_is(true),
528
        _filename(fn), _digraph(digraph),
522 529
        _use_nodes(false), _use_arcs(false),
523
        _skip_nodes(false), _skip_arcs(false) {}
530
        _skip_nodes(false), _skip_arcs(false) {
531
      if (!(*_is)) throw IoError(fn, "Cannot open file");
532
    }
524 533

	
525 534
    /// \brief Destructor
526 535
    ~DigraphReader() {
527 536
      for (typename NodeMaps::iterator it = _node_maps.begin();
528 537
           it != _node_maps.end(); ++it) {
529 538
        delete it->second;
530 539
      }
531 540

	
532 541
      for (typename ArcMaps::iterator it = _arc_maps.begin();
533 542
           it != _arc_maps.end(); ++it) {
534 543
        delete it->second;
535 544
      }
536 545

	
537 546
      for (typename Attributes::iterator it = _attributes.begin();
538 547
           it != _attributes.end(); ++it) {
539 548
        delete it->second;
540 549
      }
541 550

	
542 551
      if (local_is) {
543 552
        delete _is;
544 553
      }
545 554

	
546 555
    }
547 556

	
548 557
  private:
549 558

	
550 559
    friend DigraphReader<Digraph> digraphReader<>(std::istream& is,
551 560
                                                  Digraph& digraph);
552 561
    friend DigraphReader<Digraph> digraphReader<>(const std::string& fn,
553 562
                                                  Digraph& digraph);
554 563
    friend DigraphReader<Digraph> digraphReader<>(const char *fn,
555 564
                                                  Digraph& digraph);
556 565

	
557 566
    DigraphReader(DigraphReader& other)
558 567
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
559 568
        _use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
560 569
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
561 570

	
562 571
      other._is = 0;
563 572
      other.local_is = false;
564 573

	
565 574
      _node_index.swap(other._node_index);
566 575
      _arc_index.swap(other._arc_index);
567 576

	
568 577
      _node_maps.swap(other._node_maps);
569 578
      _arc_maps.swap(other._arc_maps);
570 579
      _attributes.swap(other._attributes);
571 580

	
572 581
      _nodes_caption = other._nodes_caption;
573 582
      _arcs_caption = other._arcs_caption;
574 583
      _attributes_caption = other._attributes_caption;
575 584

	
576 585
    }
577 586

	
578 587
    DigraphReader& operator=(const DigraphReader&);
579 588

	
580 589
  public:
581 590

	
582 591
    /// \name Reading rules
583 592
    /// @{
584 593

	
585 594
    /// \brief Node map reading rule
586 595
    ///
587 596
    /// Add a node map reading rule to the reader.
588 597
    template <typename Map>
589 598
    DigraphReader& nodeMap(const std::string& caption, Map& map) {
590 599
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
591 600
      _reader_bits::MapStorageBase<Node>* storage =
592 601
        new _reader_bits::MapStorage<Node, Map>(map);
593 602
      _node_maps.push_back(std::make_pair(caption, storage));
594 603
      return *this;
595 604
    }
596 605

	
597 606
    /// \brief Node map reading rule
598 607
    ///
599 608
    /// Add a node map reading rule with specialized converter to the
600 609
    /// reader.
601 610
    template <typename Map, typename Converter>
602 611
    DigraphReader& nodeMap(const std::string& caption, Map& map,
603 612
                           const Converter& converter = Converter()) {
604 613
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
605 614
      _reader_bits::MapStorageBase<Node>* storage =
606 615
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
607 616
      _node_maps.push_back(std::make_pair(caption, storage));
608 617
      return *this;
609 618
    }
610 619

	
611 620
    /// \brief Arc map reading rule
612 621
    ///
613 622
    /// Add an arc map reading rule to the reader.
614 623
    template <typename Map>
615 624
    DigraphReader& arcMap(const std::string& caption, Map& map) {
616 625
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
617 626
      _reader_bits::MapStorageBase<Arc>* storage =
618 627
        new _reader_bits::MapStorage<Arc, Map>(map);
619 628
      _arc_maps.push_back(std::make_pair(caption, storage));
620 629
      return *this;
621 630
    }
622 631

	
623 632
    /// \brief Arc map reading rule
624 633
    ///
625 634
    /// Add an arc map reading rule with specialized converter to the
626 635
    /// reader.
627 636
    template <typename Map, typename Converter>
628 637
    DigraphReader& arcMap(const std::string& caption, Map& map,
629 638
                          const Converter& converter = Converter()) {
630 639
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
631 640
      _reader_bits::MapStorageBase<Arc>* storage =
632 641
        new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
633 642
      _arc_maps.push_back(std::make_pair(caption, storage));
634 643
      return *this;
635 644
    }
636 645

	
637 646
    /// \brief Attribute reading rule
638 647
    ///
639 648
    /// Add an attribute reading rule to the reader.
640 649
    template <typename Value>
641 650
    DigraphReader& attribute(const std::string& caption, Value& value) {
642 651
      _reader_bits::ValueStorageBase* storage =
643 652
        new _reader_bits::ValueStorage<Value>(value);
644 653
      _attributes.insert(std::make_pair(caption, storage));
645 654
      return *this;
646 655
    }
647 656

	
648 657
    /// \brief Attribute reading rule
649 658
    ///
650 659
    /// Add an attribute reading rule with specialized converter to the
651 660
    /// reader.
652 661
    template <typename Value, typename Converter>
653 662
    DigraphReader& attribute(const std::string& caption, Value& value,
654 663
                             const Converter& converter = Converter()) {
655 664
      _reader_bits::ValueStorageBase* storage =
656 665
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
657 666
      _attributes.insert(std::make_pair(caption, storage));
658 667
      return *this;
659 668
    }
660 669

	
661 670
    /// \brief Node reading rule
662 671
    ///
663 672
    /// Add a node reading rule to reader.
664 673
    DigraphReader& node(const std::string& caption, Node& node) {
665 674
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
666 675
      Converter converter(_node_index);
667 676
      _reader_bits::ValueStorageBase* storage =
668 677
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
669 678
      _attributes.insert(std::make_pair(caption, storage));
670 679
      return *this;
671 680
    }
672 681

	
673 682
    /// \brief Arc reading rule
674 683
    ///
675 684
    /// Add an arc reading rule to reader.
676 685
    DigraphReader& arc(const std::string& caption, Arc& arc) {
677 686
      typedef _reader_bits::MapLookUpConverter<Arc> Converter;
678 687
      Converter converter(_arc_index);
679 688
      _reader_bits::ValueStorageBase* storage =
680 689
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
681 690
      _attributes.insert(std::make_pair(caption, storage));
682 691
      return *this;
683 692
    }
684 693

	
685 694
    /// @}
686 695

	
687 696
    /// \name Select section by name
688 697
    /// @{
689 698

	
690 699
    /// \brief Set \c \@nodes section to be read
691 700
    ///
692 701
    /// Set \c \@nodes section to be read
693 702
    DigraphReader& nodes(const std::string& caption) {
694 703
      _nodes_caption = caption;
695 704
      return *this;
696 705
    }
697 706

	
698 707
    /// \brief Set \c \@arcs section to be read
699 708
    ///
700 709
    /// Set \c \@arcs section to be read
701 710
    DigraphReader& arcs(const std::string& caption) {
702 711
      _arcs_caption = caption;
703 712
      return *this;
704 713
    }
705 714

	
706 715
    /// \brief Set \c \@attributes section to be read
707 716
    ///
708 717
    /// Set \c \@attributes section to be read
709 718
    DigraphReader& attributes(const std::string& caption) {
710 719
      _attributes_caption = caption;
711 720
      return *this;
712 721
    }
713 722

	
714 723
    /// @}
715 724

	
716 725
    /// \name Using previously constructed node or arc set
717 726
    /// @{
718 727

	
719 728
    /// \brief Use previously constructed node set
720 729
    ///
721 730
    /// Use previously constructed node set, and specify the node
722 731
    /// label map.
723 732
    template <typename Map>
724 733
    DigraphReader& useNodes(const Map& map) {
725 734
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
726 735
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
727 736
      _use_nodes = true;
728 737
      _writer_bits::DefaultConverter<typename Map::Value> converter;
729 738
      for (NodeIt n(_digraph); n != INVALID; ++n) {
730 739
        _node_index.insert(std::make_pair(converter(map[n]), n));
731 740
      }
732 741
      return *this;
733 742
    }
734 743

	
735 744
    /// \brief Use previously constructed node set
736 745
    ///
737 746
    /// Use previously constructed node set, and specify the node
738 747
    /// label map and a functor which converts the label map values to
739 748
    /// \c std::string.
740 749
    template <typename Map, typename Converter>
741 750
    DigraphReader& useNodes(const Map& map,
742 751
                            const Converter& converter = Converter()) {
743 752
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
744 753
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
745 754
      _use_nodes = true;
746 755
      for (NodeIt n(_digraph); n != INVALID; ++n) {
747 756
        _node_index.insert(std::make_pair(converter(map[n]), n));
748 757
      }
749 758
      return *this;
750 759
    }
751 760

	
752 761
    /// \brief Use previously constructed arc set
753 762
    ///
754 763
    /// Use previously constructed arc set, and specify the arc
755 764
    /// label map.
756 765
    template <typename Map>
757 766
    DigraphReader& useArcs(const Map& map) {
758 767
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
759 768
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
760 769
      _use_arcs = true;
761 770
      _writer_bits::DefaultConverter<typename Map::Value> converter;
762 771
      for (ArcIt a(_digraph); a != INVALID; ++a) {
763 772
        _arc_index.insert(std::make_pair(converter(map[a]), a));
764 773
      }
765 774
      return *this;
766 775
    }
767 776

	
768 777
    /// \brief Use previously constructed arc set
769 778
    ///
770 779
    /// Use previously constructed arc set, and specify the arc
771 780
    /// label map and a functor which converts the label map values to
772 781
    /// \c std::string.
773 782
    template <typename Map, typename Converter>
774 783
    DigraphReader& useArcs(const Map& map,
775 784
                           const Converter& converter = Converter()) {
776 785
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
777 786
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
778 787
      _use_arcs = true;
779 788
      for (ArcIt a(_digraph); a != INVALID; ++a) {
780 789
        _arc_index.insert(std::make_pair(converter(map[a]), a));
781 790
      }
782 791
      return *this;
783 792
    }
784 793

	
785 794
    /// \brief Skips the reading of node section
786 795
    ///
787 796
    /// Omit the reading of the node section. This implies that each node
788 797
    /// map reading rule will be abandoned, and the nodes of the graph
789 798
    /// will not be constructed, which usually cause that the arc set
790 799
    /// could not be read due to lack of node name resolving.
791 800
    /// Therefore \c skipArcs() function should also be used, or
792 801
    /// \c useNodes() should be used to specify the label of the nodes.
793 802
    DigraphReader& skipNodes() {
794 803
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
795 804
      _skip_nodes = true;
796 805
      return *this;
797 806
    }
798 807

	
799 808
    /// \brief Skips the reading of arc section
800 809
    ///
801 810
    /// Omit the reading of the arc section. This implies that each arc
802 811
    /// map reading rule will be abandoned, and the arcs of the graph
803 812
    /// will not be constructed.
804 813
    DigraphReader& skipArcs() {
805 814
      LEMON_ASSERT(!_skip_arcs, "Skip arcs already set");
806 815
      _skip_arcs = true;
807 816
      return *this;
808 817
    }
809 818

	
810 819
    /// @}
811 820

	
812 821
  private:
813 822

	
814 823
    bool readLine() {
815 824
      std::string str;
816 825
      while(++line_num, std::getline(*_is, str)) {
817 826
        line.clear(); line.str(str);
818 827
        char c;
819 828
        if (line >> std::ws >> c && c != '#') {
820 829
          line.putback(c);
821 830
          return true;
822 831
        }
823 832
      }
824 833
      return false;
825 834
    }
826 835

	
827 836
    bool readSuccess() {
828 837
      return static_cast<bool>(*_is);
829 838
    }
830 839

	
831 840
    void skipSection() {
832 841
      char c;
833 842
      while (readSuccess() && line >> c && c != '@') {
834 843
        readLine();
835 844
      }
836 845
      line.putback(c);
837 846
    }
838 847

	
839 848
    void readNodes() {
840 849

	
841 850
      std::vector<int> map_index(_node_maps.size());
842 851
      int map_num, label_index;
843 852

	
844 853
      char c;
845 854
      if (!readLine() || !(line >> c) || c == '@') {
846 855
        if (readSuccess() && line) line.putback(c);
847 856
        if (!_node_maps.empty())
848
          throw DataFormatError("Cannot find map names");
857
          throw FormatError("Cannot find map names");
849 858
        return;
850 859
      }
851 860
      line.putback(c);
852 861

	
853 862
      {
854 863
        std::map<std::string, int> maps;
855 864

	
856 865
        std::string map;
857 866
        int index = 0;
858 867
        while (_reader_bits::readToken(line, map)) {
859 868
          if (maps.find(map) != maps.end()) {
860 869
            std::ostringstream msg;
861 870
            msg << "Multiple occurence of node map: " << map;
862
            throw DataFormatError(msg.str().c_str());
871
            throw FormatError(msg.str());
863 872
          }
864 873
          maps.insert(std::make_pair(map, index));
865 874
          ++index;
866 875
        }
867 876

	
868 877
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
869 878
          std::map<std::string, int>::iterator jt =
870 879
            maps.find(_node_maps[i].first);
871 880
          if (jt == maps.end()) {
872 881
            std::ostringstream msg;
873 882
            msg << "Map not found in file: " << _node_maps[i].first;
874
            throw DataFormatError(msg.str().c_str());
883
            throw FormatError(msg.str());
875 884
          }
876 885
          map_index[i] = jt->second;
877 886
        }
878 887

	
879 888
        {
880 889
          std::map<std::string, int>::iterator jt = maps.find("label");
881 890
          if (jt != maps.end()) {
882 891
            label_index = jt->second;
883 892
          } else {
884 893
            label_index = -1;
885 894
          }
886 895
        }
887 896
        map_num = maps.size();
888 897
      }
889 898

	
890 899
      while (readLine() && line >> c && c != '@') {
891 900
        line.putback(c);
892 901

	
893 902
        std::vector<std::string> tokens(map_num);
894 903
        for (int i = 0; i < map_num; ++i) {
895 904
          if (!_reader_bits::readToken(line, tokens[i])) {
896 905
            std::ostringstream msg;
897 906
            msg << "Column not found (" << i + 1 << ")";
898
            throw DataFormatError(msg.str().c_str());
907
            throw FormatError(msg.str());
899 908
          }
900 909
        }
901 910
        if (line >> std::ws >> c)
902
          throw DataFormatError("Extra character on the end of line");
911
          throw FormatError("Extra character on the end of line");
903 912

	
904 913
        Node n;
905 914
        if (!_use_nodes) {
906 915
          n = _digraph.addNode();
907 916
          if (label_index != -1)
908 917
            _node_index.insert(std::make_pair(tokens[label_index], n));
909 918
        } else {
910 919
          if (label_index == -1)
911
            throw DataFormatError("Label map not found in file");
920
            throw FormatError("Label map not found in file");
912 921
          typename std::map<std::string, Node>::iterator it =
913 922
            _node_index.find(tokens[label_index]);
914 923
          if (it == _node_index.end()) {
915 924
            std::ostringstream msg;
916 925
            msg << "Node with label not found: " << tokens[label_index];
917
            throw DataFormatError(msg.str().c_str());
926
            throw FormatError(msg.str());
918 927
          }
919 928
          n = it->second;
920 929
        }
921 930

	
922 931
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
923 932
          _node_maps[i].second->set(n, tokens[map_index[i]]);
924 933
        }
925 934

	
926 935
      }
927 936
      if (readSuccess()) {
928 937
        line.putback(c);
929 938
      }
930 939
    }
931 940

	
932 941
    void readArcs() {
933 942

	
934 943
      std::vector<int> map_index(_arc_maps.size());
935 944
      int map_num, label_index;
936 945

	
937 946
      char c;
938 947
      if (!readLine() || !(line >> c) || c == '@') {
939 948
        if (readSuccess() && line) line.putback(c);
940 949
        if (!_arc_maps.empty())
941
          throw DataFormatError("Cannot find map names");
950
          throw FormatError("Cannot find map names");
942 951
        return;
943 952
      }
944 953
      line.putback(c);
945 954

	
946 955
      {
947 956
        std::map<std::string, int> maps;
948 957

	
949 958
        std::string map;
950 959
        int index = 0;
951 960
        while (_reader_bits::readToken(line, map)) {
952 961
          if (maps.find(map) != maps.end()) {
953 962
            std::ostringstream msg;
954 963
            msg << "Multiple occurence of arc map: " << map;
955
            throw DataFormatError(msg.str().c_str());
964
            throw FormatError(msg.str());
956 965
          }
957 966
          maps.insert(std::make_pair(map, index));
958 967
          ++index;
959 968
        }
960 969

	
961 970
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
962 971
          std::map<std::string, int>::iterator jt =
963 972
            maps.find(_arc_maps[i].first);
964 973
          if (jt == maps.end()) {
965 974
            std::ostringstream msg;
966 975
            msg << "Map not found in file: " << _arc_maps[i].first;
967
            throw DataFormatError(msg.str().c_str());
976
            throw FormatError(msg.str());
968 977
          }
969 978
          map_index[i] = jt->second;
970 979
        }
971 980

	
972 981
        {
973 982
          std::map<std::string, int>::iterator jt = maps.find("label");
974 983
          if (jt != maps.end()) {
975 984
            label_index = jt->second;
976 985
          } else {
977 986
            label_index = -1;
978 987
          }
979 988
        }
980 989
        map_num = maps.size();
981 990
      }
982 991

	
983 992
      while (readLine() && line >> c && c != '@') {
984 993
        line.putback(c);
985 994

	
986 995
        std::string source_token;
987 996
        std::string target_token;
988 997

	
989 998
        if (!_reader_bits::readToken(line, source_token))
990
          throw DataFormatError("Source not found");
999
          throw FormatError("Source not found");
991 1000

	
992 1001
        if (!_reader_bits::readToken(line, target_token))
993
          throw DataFormatError("Target not found");
1002
          throw FormatError("Target not found");
994 1003

	
995 1004
        std::vector<std::string> tokens(map_num);
996 1005
        for (int i = 0; i < map_num; ++i) {
997 1006
          if (!_reader_bits::readToken(line, tokens[i])) {
998 1007
            std::ostringstream msg;
999 1008
            msg << "Column not found (" << i + 1 << ")";
1000
            throw DataFormatError(msg.str().c_str());
1009
            throw FormatError(msg.str());
1001 1010
          }
1002 1011
        }
1003 1012
        if (line >> std::ws >> c)
1004
          throw DataFormatError("Extra character on the end of line");
1013
          throw FormatError("Extra character on the end of line");
1005 1014

	
1006 1015
        Arc a;
1007 1016
        if (!_use_arcs) {
1008 1017

	
1009 1018
          typename NodeIndex::iterator it;
1010 1019

	
1011 1020
          it = _node_index.find(source_token);
1012 1021
          if (it == _node_index.end()) {
1013 1022
            std::ostringstream msg;
1014 1023
            msg << "Item not found: " << source_token;
1015
            throw DataFormatError(msg.str().c_str());
1024
            throw FormatError(msg.str());
1016 1025
          }
1017 1026
          Node source = it->second;
1018 1027

	
1019 1028
          it = _node_index.find(target_token);
1020 1029
          if (it == _node_index.end()) {
1021 1030
            std::ostringstream msg;
1022 1031
            msg << "Item not found: " << target_token;
1023
            throw DataFormatError(msg.str().c_str());
1032
            throw FormatError(msg.str());
1024 1033
          }
1025 1034
          Node target = it->second;
1026 1035

	
1027 1036
          a = _digraph.addArc(source, target);
1028 1037
          if (label_index != -1)
1029 1038
            _arc_index.insert(std::make_pair(tokens[label_index], a));
1030 1039
        } else {
1031 1040
          if (label_index == -1)
1032
            throw DataFormatError("Label map not found in file");
1041
            throw FormatError("Label map not found in file");
1033 1042
          typename std::map<std::string, Arc>::iterator it =
1034 1043
            _arc_index.find(tokens[label_index]);
1035 1044
          if (it == _arc_index.end()) {
1036 1045
            std::ostringstream msg;
1037 1046
            msg << "Arc with label not found: " << tokens[label_index];
1038
            throw DataFormatError(msg.str().c_str());
1047
            throw FormatError(msg.str());
1039 1048
          }
1040 1049
          a = it->second;
1041 1050
        }
1042 1051

	
1043 1052
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1044 1053
          _arc_maps[i].second->set(a, tokens[map_index[i]]);
1045 1054
        }
1046 1055

	
1047 1056
      }
1048 1057
      if (readSuccess()) {
1049 1058
        line.putback(c);
1050 1059
      }
1051 1060
    }
1052 1061

	
1053 1062
    void readAttributes() {
1054 1063

	
1055 1064
      std::set<std::string> read_attr;
1056 1065

	
1057 1066
      char c;
1058 1067
      while (readLine() && line >> c && c != '@') {
1059 1068
        line.putback(c);
1060 1069

	
1061 1070
        std::string attr, token;
1062 1071
        if (!_reader_bits::readToken(line, attr))
1063
          throw DataFormatError("Attribute name not found");
1072
          throw FormatError("Attribute name not found");
1064 1073
        if (!_reader_bits::readToken(line, token))
1065
          throw DataFormatError("Attribute value not found");
1074
          throw FormatError("Attribute value not found");
1066 1075
        if (line >> c)
1067
          throw DataFormatError("Extra character on the end of line");
1076
          throw FormatError("Extra character on the end of line");
1068 1077

	
1069 1078
        {
1070 1079
          std::set<std::string>::iterator it = read_attr.find(attr);
1071 1080
          if (it != read_attr.end()) {
1072 1081
            std::ostringstream msg;
1073 1082
            msg << "Multiple occurence of attribute " << attr;
1074
            throw DataFormatError(msg.str().c_str());
1083
            throw FormatError(msg.str());
1075 1084
          }
1076 1085
          read_attr.insert(attr);
1077 1086
        }
1078 1087

	
1079 1088
        {
1080 1089
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1081 1090
          while (it != _attributes.end() && it->first == attr) {
1082 1091
            it->second->set(token);
1083 1092
            ++it;
1084 1093
          }
1085 1094
        }
1086 1095

	
1087 1096
      }
1088 1097
      if (readSuccess()) {
1089 1098
        line.putback(c);
1090 1099
      }
1091 1100
      for (typename Attributes::iterator it = _attributes.begin();
1092 1101
           it != _attributes.end(); ++it) {
1093 1102
        if (read_attr.find(it->first) == read_attr.end()) {
1094 1103
          std::ostringstream msg;
1095 1104
          msg << "Attribute not found in file: " << it->first;
1096
          throw DataFormatError(msg.str().c_str());
1105
          throw FormatError(msg.str());
1097 1106
        }
1098 1107
      }
1099 1108
    }
1100 1109

	
1101 1110
  public:
1102 1111

	
1103 1112
    /// \name Execution of the reader
1104 1113
    /// @{
1105 1114

	
1106 1115
    /// \brief Start the batch processing
1107 1116
    ///
1108 1117
    /// This function starts the batch processing
1109 1118
    void run() {
1110 1119
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1111 1120
      if (!*_is) {
1112
        throw DataFormatError("Cannot find file");
1121
        throw FormatError("Cannot find file");
1113 1122
      }
1114 1123

	
1115 1124
      bool nodes_done = _skip_nodes;
1116 1125
      bool arcs_done = _skip_arcs;
1117 1126
      bool attributes_done = false;
1118 1127

	
1119 1128
      line_num = 0;
1120 1129
      readLine();
1121 1130
      skipSection();
1122 1131

	
1123 1132
      while (readSuccess()) {
1124 1133
        try {
1125 1134
          char c;
1126 1135
          std::string section, caption;
1127 1136
          line >> c;
1128 1137
          _reader_bits::readToken(line, section);
1129 1138
          _reader_bits::readToken(line, caption);
1130 1139

	
1131 1140
          if (line >> c)
1132
            throw DataFormatError("Extra character on the end of line");
1141
            throw FormatError("Extra character on the end of line");
1133 1142

	
1134 1143
          if (section == "nodes" && !nodes_done) {
1135 1144
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1136 1145
              readNodes();
1137 1146
              nodes_done = true;
1138 1147
            }
1139 1148
          } else if ((section == "arcs" || section == "edges") &&
1140 1149
                     !arcs_done) {
1141 1150
            if (_arcs_caption.empty() || _arcs_caption == caption) {
1142 1151
              readArcs();
1143 1152
              arcs_done = true;
1144 1153
            }
1145 1154
          } else if (section == "attributes" && !attributes_done) {
1146 1155
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1147 1156
              readAttributes();
1148 1157
              attributes_done = true;
1149 1158
            }
1150 1159
          } else {
1151 1160
            readLine();
1152 1161
            skipSection();
1153 1162
          }
1154
        } catch (DataFormatError& error) {
1163
        } catch (FormatError& error) {
1155 1164
          error.line(line_num);
1165
          error.file(_filename);
1156 1166
          throw;
1157 1167
        }
1158 1168
      }
1159 1169

	
1160 1170
      if (!nodes_done) {
1161
        throw DataFormatError("Section @nodes not found");
1171
        throw FormatError("Section @nodes not found");
1162 1172
      }
1163 1173

	
1164 1174
      if (!arcs_done) {
1165
        throw DataFormatError("Section @arcs not found");
1175
        throw FormatError("Section @arcs not found");
1166 1176
      }
1167 1177

	
1168 1178
      if (!attributes_done && !_attributes.empty()) {
1169
        throw DataFormatError("Section @attributes not found");
1179
        throw FormatError("Section @attributes not found");
1170 1180
      }
1171 1181

	
1172 1182
    }
1173 1183

	
1174 1184
    /// @}
1175 1185

	
1176 1186
  };
1177 1187

	
1178 1188
  /// \brief Return a \ref DigraphReader class
1179 1189
  ///
1180 1190
  /// This function just returns a \ref DigraphReader class.
1181 1191
  /// \relates DigraphReader
1182 1192
  template <typename Digraph>
1183 1193
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
1184 1194
    DigraphReader<Digraph> tmp(is, digraph);
1185 1195
    return tmp;
1186 1196
  }
1187 1197

	
1188 1198
  /// \brief Return a \ref DigraphReader class
1189 1199
  ///
1190 1200
  /// This function just returns a \ref DigraphReader class.
1191 1201
  /// \relates DigraphReader
1192 1202
  template <typename Digraph>
1193 1203
  DigraphReader<Digraph> digraphReader(const std::string& fn,
1194 1204
                                       Digraph& digraph) {
1195 1205
    DigraphReader<Digraph> tmp(fn, digraph);
1196 1206
    return tmp;
1197 1207
  }
1198 1208

	
1199 1209
  /// \brief Return a \ref DigraphReader class
1200 1210
  ///
1201 1211
  /// This function just returns a \ref DigraphReader class.
1202 1212
  /// \relates DigraphReader
1203 1213
  template <typename Digraph>
1204 1214
  DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
1205 1215
    DigraphReader<Digraph> tmp(fn, digraph);
1206 1216
    return tmp;
1207 1217
  }
1208 1218

	
1209 1219
  template <typename Graph>
1210 1220
  class GraphReader;
1211 1221

	
1212 1222
  template <typename Graph>
1213 1223
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph);
1214 1224

	
1215 1225
  template <typename Graph>
1216 1226
  GraphReader<Graph> graphReader(const std::string& fn, Graph& graph);
1217 1227

	
1218 1228
  template <typename Graph>
1219 1229
  GraphReader<Graph> graphReader(const char *fn, Graph& graph);
1220 1230

	
1221 1231
  /// \ingroup lemon_io
1222 1232
  ///
1223 1233
  /// \brief \ref lgf-format "LGF" reader for undirected graphs
1224 1234
  ///
1225 1235
  /// This utility reads an \ref lgf-format "LGF" file.
1226 1236
  ///
1227 1237
  /// It can be used almost the same way as \c DigraphReader.
1228 1238
  /// The only difference is that this class can handle edges and
1229 1239
  /// edge maps as well as arcs and arc maps.
1230 1240
  ///
1231 1241
  /// The columns in the \c \@edges (or \c \@arcs) section are the
1232 1242
  /// edge maps. However, if there are two maps with the same name
1233 1243
  /// prefixed with \c '+' and \c '-', then these can be read into an
1234 1244
  /// arc map.  Similarly, an attribute can be read into an arc, if
1235 1245
  /// it's value is an edge label prefixed with \c '+' or \c '-'.
1236 1246
  template <typename _Graph>
1237 1247
  class GraphReader {
1238 1248
  public:
1239 1249

	
1240 1250
    typedef _Graph Graph;
1241 1251
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1242 1252

	
1243 1253
  private:
1244 1254

	
1245 1255
    std::istream* _is;
1246 1256
    bool local_is;
1257
    std::string _filename;
1247 1258

	
1248 1259
    Graph& _graph;
1249 1260

	
1250 1261
    std::string _nodes_caption;
1251 1262
    std::string _edges_caption;
1252 1263
    std::string _attributes_caption;
1253 1264

	
1254 1265
    typedef std::map<std::string, Node> NodeIndex;
1255 1266
    NodeIndex _node_index;
1256 1267
    typedef std::map<std::string, Edge> EdgeIndex;
1257 1268
    EdgeIndex _edge_index;
1258 1269

	
1259 1270
    typedef std::vector<std::pair<std::string,
1260 1271
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1261 1272
    NodeMaps _node_maps;
1262 1273

	
1263 1274
    typedef std::vector<std::pair<std::string,
1264 1275
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1265 1276
    EdgeMaps _edge_maps;
1266 1277

	
1267 1278
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1268 1279
      Attributes;
1269 1280
    Attributes _attributes;
1270 1281

	
1271 1282
    bool _use_nodes;
1272 1283
    bool _use_edges;
1273 1284

	
1274 1285
    bool _skip_nodes;
1275 1286
    bool _skip_edges;
1276 1287

	
1277 1288
    int line_num;
1278 1289
    std::istringstream line;
1279 1290

	
1280 1291
  public:
1281 1292

	
1282 1293
    /// \brief Constructor
1283 1294
    ///
1284 1295
    /// Construct an undirected graph reader, which reads from the given
1285 1296
    /// input stream.
1286 1297
    GraphReader(std::istream& is, Graph& graph)
1287 1298
      : _is(&is), local_is(false), _graph(graph),
1288 1299
        _use_nodes(false), _use_edges(false),
1289 1300
        _skip_nodes(false), _skip_edges(false) {}
1290 1301

	
1291 1302
    /// \brief Constructor
1292 1303
    ///
1293 1304
    /// Construct an undirected graph reader, which reads from the given
1294 1305
    /// file.
1295 1306
    GraphReader(const std::string& fn, Graph& graph)
1296
      : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph),
1307
      : _is(new std::ifstream(fn.c_str())), local_is(true),
1308
        _filename(fn), _graph(graph),
1297 1309
        _use_nodes(false), _use_edges(false),
1298
        _skip_nodes(false), _skip_edges(false) {}
1310
        _skip_nodes(false), _skip_edges(false) {
1311
      if (!(*_is)) throw IoError(fn, "Cannot open file");
1312
    }
1299 1313

	
1300 1314
    /// \brief Constructor
1301 1315
    ///
1302 1316
    /// Construct an undirected graph reader, which reads from the given
1303 1317
    /// file.
1304 1318
    GraphReader(const char* fn, Graph& graph)
1305
      : _is(new std::ifstream(fn)), local_is(true), _graph(graph),
1319
      : _is(new std::ifstream(fn)), local_is(true),
1320
        _filename(fn), _graph(graph),
1306 1321
        _use_nodes(false), _use_edges(false),
1307
        _skip_nodes(false), _skip_edges(false) {}
1322
        _skip_nodes(false), _skip_edges(false) {
1323
      if (!(*_is)) throw IoError(fn, "Cannot open file");
1324
    }
1308 1325

	
1309 1326
    /// \brief Destructor
1310 1327
    ~GraphReader() {
1311 1328
      for (typename NodeMaps::iterator it = _node_maps.begin();
1312 1329
           it != _node_maps.end(); ++it) {
1313 1330
        delete it->second;
1314 1331
      }
1315 1332

	
1316 1333
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1317 1334
           it != _edge_maps.end(); ++it) {
1318 1335
        delete it->second;
1319 1336
      }
1320 1337

	
1321 1338
      for (typename Attributes::iterator it = _attributes.begin();
1322 1339
           it != _attributes.end(); ++it) {
1323 1340
        delete it->second;
1324 1341
      }
1325 1342

	
1326 1343
      if (local_is) {
1327 1344
        delete _is;
1328 1345
      }
1329 1346

	
1330 1347
    }
1331 1348

	
1332 1349
  private:
1333 1350
    friend GraphReader<Graph> graphReader<>(std::istream& is, Graph& graph);
1334 1351
    friend GraphReader<Graph> graphReader<>(const std::string& fn,
1335 1352
                                            Graph& graph);
1336 1353
    friend GraphReader<Graph> graphReader<>(const char *fn, Graph& graph);
1337 1354

	
1338 1355
    GraphReader(GraphReader& other)
1339 1356
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1340 1357
        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
1341 1358
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1342 1359

	
1343 1360
      other._is = 0;
1344 1361
      other.local_is = false;
1345 1362

	
1346 1363
      _node_index.swap(other._node_index);
1347 1364
      _edge_index.swap(other._edge_index);
1348 1365

	
1349 1366
      _node_maps.swap(other._node_maps);
1350 1367
      _edge_maps.swap(other._edge_maps);
1351 1368
      _attributes.swap(other._attributes);
1352 1369

	
1353 1370
      _nodes_caption = other._nodes_caption;
1354 1371
      _edges_caption = other._edges_caption;
1355 1372
      _attributes_caption = other._attributes_caption;
1356 1373

	
1357 1374
    }
1358 1375

	
1359 1376
    GraphReader& operator=(const GraphReader&);
1360 1377

	
1361 1378
  public:
1362 1379

	
1363 1380
    /// \name Reading rules
1364 1381
    /// @{
1365 1382

	
1366 1383
    /// \brief Node map reading rule
1367 1384
    ///
1368 1385
    /// Add a node map reading rule to the reader.
1369 1386
    template <typename Map>
1370 1387
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1371 1388
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1372 1389
      _reader_bits::MapStorageBase<Node>* storage =
1373 1390
        new _reader_bits::MapStorage<Node, Map>(map);
1374 1391
      _node_maps.push_back(std::make_pair(caption, storage));
1375 1392
      return *this;
1376 1393
    }
1377 1394

	
1378 1395
    /// \brief Node map reading rule
1379 1396
    ///
1380 1397
    /// Add a node map reading rule with specialized converter to the
1381 1398
    /// reader.
1382 1399
    template <typename Map, typename Converter>
1383 1400
    GraphReader& nodeMap(const std::string& caption, Map& map,
1384 1401
                           const Converter& converter = Converter()) {
1385 1402
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1386 1403
      _reader_bits::MapStorageBase<Node>* storage =
1387 1404
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1388 1405
      _node_maps.push_back(std::make_pair(caption, storage));
1389 1406
      return *this;
1390 1407
    }
1391 1408

	
1392 1409
    /// \brief Edge map reading rule
1393 1410
    ///
1394 1411
    /// Add an edge map reading rule to the reader.
1395 1412
    template <typename Map>
1396 1413
    GraphReader& edgeMap(const std::string& caption, Map& map) {
1397 1414
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1398 1415
      _reader_bits::MapStorageBase<Edge>* storage =
1399 1416
        new _reader_bits::MapStorage<Edge, Map>(map);
1400 1417
      _edge_maps.push_back(std::make_pair(caption, storage));
1401 1418
      return *this;
1402 1419
    }
1403 1420

	
1404 1421
    /// \brief Edge map reading rule
1405 1422
    ///
1406 1423
    /// Add an edge map reading rule with specialized converter to the
1407 1424
    /// reader.
1408 1425
    template <typename Map, typename Converter>
1409 1426
    GraphReader& edgeMap(const std::string& caption, Map& map,
1410 1427
                          const Converter& converter = Converter()) {
1411 1428
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1412 1429
      _reader_bits::MapStorageBase<Edge>* storage =
1413 1430
        new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1414 1431
      _edge_maps.push_back(std::make_pair(caption, storage));
1415 1432
      return *this;
1416 1433
    }
1417 1434

	
1418 1435
    /// \brief Arc map reading rule
1419 1436
    ///
1420 1437
    /// Add an arc map reading rule to the reader.
1421 1438
    template <typename Map>
1422 1439
    GraphReader& arcMap(const std::string& caption, Map& map) {
1423 1440
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1424 1441
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1425 1442
        new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1426 1443
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1427 1444
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1428 1445
        new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1429 1446
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1430 1447
      return *this;
1431 1448
    }
1432 1449

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

	
1452 1469
    /// \brief Attribute reading rule
1453 1470
    ///
1454 1471
    /// Add an attribute reading rule to the reader.
1455 1472
    template <typename Value>
1456 1473
    GraphReader& attribute(const std::string& caption, Value& value) {
1457 1474
      _reader_bits::ValueStorageBase* storage =
1458 1475
        new _reader_bits::ValueStorage<Value>(value);
1459 1476
      _attributes.insert(std::make_pair(caption, storage));
1460 1477
      return *this;
1461 1478
    }
1462 1479

	
1463 1480
    /// \brief Attribute reading rule
1464 1481
    ///
1465 1482
    /// Add an attribute reading rule with specialized converter to the
1466 1483
    /// reader.
1467 1484
    template <typename Value, typename Converter>
1468 1485
    GraphReader& attribute(const std::string& caption, Value& value,
1469 1486
                             const Converter& converter = Converter()) {
1470 1487
      _reader_bits::ValueStorageBase* storage =
1471 1488
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1472 1489
      _attributes.insert(std::make_pair(caption, storage));
1473 1490
      return *this;
1474 1491
    }
1475 1492

	
1476 1493
    /// \brief Node reading rule
1477 1494
    ///
1478 1495
    /// Add a node reading rule to reader.
1479 1496
    GraphReader& node(const std::string& caption, Node& node) {
1480 1497
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
1481 1498
      Converter converter(_node_index);
1482 1499
      _reader_bits::ValueStorageBase* storage =
1483 1500
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1484 1501
      _attributes.insert(std::make_pair(caption, storage));
1485 1502
      return *this;
1486 1503
    }
1487 1504

	
1488 1505
    /// \brief Edge reading rule
1489 1506
    ///
1490 1507
    /// Add an edge reading rule to reader.
1491 1508
    GraphReader& edge(const std::string& caption, Edge& edge) {
1492 1509
      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1493 1510
      Converter converter(_edge_index);
1494 1511
      _reader_bits::ValueStorageBase* storage =
1495 1512
        new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1496 1513
      _attributes.insert(std::make_pair(caption, storage));
1497 1514
      return *this;
1498 1515
    }
1499 1516

	
1500 1517
    /// \brief Arc reading rule
1501 1518
    ///
1502 1519
    /// Add an arc reading rule to reader.
1503 1520
    GraphReader& arc(const std::string& caption, Arc& arc) {
1504 1521
      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
1505 1522
      Converter converter(_graph, _edge_index);
1506 1523
      _reader_bits::ValueStorageBase* storage =
1507 1524
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1508 1525
      _attributes.insert(std::make_pair(caption, storage));
1509 1526
      return *this;
1510 1527
    }
1511 1528

	
1512 1529
    /// @}
1513 1530

	
1514 1531
    /// \name Select section by name
1515 1532
    /// @{
1516 1533

	
1517 1534
    /// \brief Set \c \@nodes section to be read
1518 1535
    ///
1519 1536
    /// Set \c \@nodes section to be read.
1520 1537
    GraphReader& nodes(const std::string& caption) {
1521 1538
      _nodes_caption = caption;
1522 1539
      return *this;
1523 1540
    }
1524 1541

	
1525 1542
    /// \brief Set \c \@edges section to be read
1526 1543
    ///
1527 1544
    /// Set \c \@edges section to be read.
1528 1545
    GraphReader& edges(const std::string& caption) {
1529 1546
      _edges_caption = caption;
1530 1547
      return *this;
1531 1548
    }
1532 1549

	
1533 1550
    /// \brief Set \c \@attributes section to be read
1534 1551
    ///
1535 1552
    /// Set \c \@attributes section to be read.
1536 1553
    GraphReader& attributes(const std::string& caption) {
1537 1554
      _attributes_caption = caption;
1538 1555
      return *this;
1539 1556
    }
1540 1557

	
1541 1558
    /// @}
1542 1559

	
1543 1560
    /// \name Using previously constructed node or edge set
1544 1561
    /// @{
1545 1562

	
1546 1563
    /// \brief Use previously constructed node set
1547 1564
    ///
1548 1565
    /// Use previously constructed node set, and specify the node
1549 1566
    /// label map.
1550 1567
    template <typename Map>
1551 1568
    GraphReader& useNodes(const Map& map) {
1552 1569
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1553 1570
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1554 1571
      _use_nodes = true;
1555 1572
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1556 1573
      for (NodeIt n(_graph); n != INVALID; ++n) {
1557 1574
        _node_index.insert(std::make_pair(converter(map[n]), n));
1558 1575
      }
1559 1576
      return *this;
1560 1577
    }
1561 1578

	
1562 1579
    /// \brief Use previously constructed node set
1563 1580
    ///
1564 1581
    /// Use previously constructed node set, and specify the node
1565 1582
    /// label map and a functor which converts the label map values to
1566 1583
    /// \c std::string.
1567 1584
    template <typename Map, typename Converter>
1568 1585
    GraphReader& useNodes(const Map& map,
1569 1586
                            const Converter& converter = Converter()) {
1570 1587
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1571 1588
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1572 1589
      _use_nodes = true;
1573 1590
      for (NodeIt n(_graph); n != INVALID; ++n) {
1574 1591
        _node_index.insert(std::make_pair(converter(map[n]), n));
1575 1592
      }
1576 1593
      return *this;
1577 1594
    }
1578 1595

	
1579 1596
    /// \brief Use previously constructed edge set
1580 1597
    ///
1581 1598
    /// Use previously constructed edge set, and specify the edge
1582 1599
    /// label map.
1583 1600
    template <typename Map>
1584 1601
    GraphReader& useEdges(const Map& map) {
1585 1602
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1586 1603
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1587 1604
      _use_edges = true;
1588 1605
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1589 1606
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1590 1607
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1591 1608
      }
1592 1609
      return *this;
1593 1610
    }
1594 1611

	
1595 1612
    /// \brief Use previously constructed edge set
1596 1613
    ///
1597 1614
    /// Use previously constructed edge set, and specify the edge
1598 1615
    /// label map and a functor which converts the label map values to
1599 1616
    /// \c std::string.
1600 1617
    template <typename Map, typename Converter>
1601 1618
    GraphReader& useEdges(const Map& map,
1602 1619
                            const Converter& converter = Converter()) {
1603 1620
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1604 1621
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1605 1622
      _use_edges = true;
1606 1623
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1607 1624
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1608 1625
      }
1609 1626
      return *this;
1610 1627
    }
1611 1628

	
1612 1629
    /// \brief Skip the reading of node section
1613 1630
    ///
1614 1631
    /// Omit the reading of the node section. This implies that each node
1615 1632
    /// map reading rule will be abandoned, and the nodes of the graph
1616 1633
    /// will not be constructed, which usually cause that the edge set
1617 1634
    /// could not be read due to lack of node name
1618 1635
    /// could not be read due to lack of node name resolving.
1619 1636
    /// Therefore \c skipEdges() function should also be used, or
1620 1637
    /// \c useNodes() should be used to specify the label of the nodes.
1621 1638
    GraphReader& skipNodes() {
1622 1639
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
1623 1640
      _skip_nodes = true;
1624 1641
      return *this;
1625 1642
    }
1626 1643

	
1627 1644
    /// \brief Skip the reading of edge section
1628 1645
    ///
1629 1646
    /// Omit the reading of the edge section. This implies that each edge
1630 1647
    /// map reading rule will be abandoned, and the edges of the graph
1631 1648
    /// will not be constructed.
1632 1649
    GraphReader& skipEdges() {
1633 1650
      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
1634 1651
      _skip_edges = true;
1635 1652
      return *this;
1636 1653
    }
1637 1654

	
1638 1655
    /// @}
1639 1656

	
1640 1657
  private:
1641 1658

	
1642 1659
    bool readLine() {
1643 1660
      std::string str;
1644 1661
      while(++line_num, std::getline(*_is, str)) {
1645 1662
        line.clear(); line.str(str);
1646 1663
        char c;
1647 1664
        if (line >> std::ws >> c && c != '#') {
1648 1665
          line.putback(c);
1649 1666
          return true;
1650 1667
        }
1651 1668
      }
1652 1669
      return false;
1653 1670
    }
1654 1671

	
1655 1672
    bool readSuccess() {
1656 1673
      return static_cast<bool>(*_is);
1657 1674
    }
1658 1675

	
1659 1676
    void skipSection() {
1660 1677
      char c;
1661 1678
      while (readSuccess() && line >> c && c != '@') {
1662 1679
        readLine();
1663 1680
      }
1664 1681
      line.putback(c);
1665 1682
    }
1666 1683

	
1667 1684
    void readNodes() {
1668 1685

	
1669 1686
      std::vector<int> map_index(_node_maps.size());
1670 1687
      int map_num, label_index;
1671 1688

	
1672 1689
      char c;
1673 1690
      if (!readLine() || !(line >> c) || c == '@') {
1674 1691
        if (readSuccess() && line) line.putback(c);
1675 1692
        if (!_node_maps.empty())
1676
          throw DataFormatError("Cannot find map names");
1693
          throw FormatError("Cannot find map names");
1677 1694
        return;
1678 1695
      }
1679 1696
      line.putback(c);
1680 1697

	
1681 1698
      {
1682 1699
        std::map<std::string, int> maps;
1683 1700

	
1684 1701
        std::string map;
1685 1702
        int index = 0;
1686 1703
        while (_reader_bits::readToken(line, map)) {
1687 1704
          if (maps.find(map) != maps.end()) {
1688 1705
            std::ostringstream msg;
1689 1706
            msg << "Multiple occurence of node map: " << map;
1690
            throw DataFormatError(msg.str().c_str());
1707
            throw FormatError(msg.str());
1691 1708
          }
1692 1709
          maps.insert(std::make_pair(map, index));
1693 1710
          ++index;
1694 1711
        }
1695 1712

	
1696 1713
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1697 1714
          std::map<std::string, int>::iterator jt =
1698 1715
            maps.find(_node_maps[i].first);
1699 1716
          if (jt == maps.end()) {
1700 1717
            std::ostringstream msg;
1701 1718
            msg << "Map not found in file: " << _node_maps[i].first;
1702
            throw DataFormatError(msg.str().c_str());
1719
            throw FormatError(msg.str());
1703 1720
          }
1704 1721
          map_index[i] = jt->second;
1705 1722
        }
1706 1723

	
1707 1724
        {
1708 1725
          std::map<std::string, int>::iterator jt = maps.find("label");
1709 1726
          if (jt != maps.end()) {
1710 1727
            label_index = jt->second;
1711 1728
          } else {
1712 1729
            label_index = -1;
1713 1730
          }
1714 1731
        }
1715 1732
        map_num = maps.size();
1716 1733
      }
1717 1734

	
1718 1735
      while (readLine() && line >> c && c != '@') {
1719 1736
        line.putback(c);
1720 1737

	
1721 1738
        std::vector<std::string> tokens(map_num);
1722 1739
        for (int i = 0; i < map_num; ++i) {
1723 1740
          if (!_reader_bits::readToken(line, tokens[i])) {
1724 1741
            std::ostringstream msg;
1725 1742
            msg << "Column not found (" << i + 1 << ")";
1726
            throw DataFormatError(msg.str().c_str());
1743
            throw FormatError(msg.str());
1727 1744
          }
1728 1745
        }
1729 1746
        if (line >> std::ws >> c)
1730
          throw DataFormatError("Extra character on the end of line");
1747
          throw FormatError("Extra character on the end of line");
1731 1748

	
1732 1749
        Node n;
1733 1750
        if (!_use_nodes) {
1734 1751
          n = _graph.addNode();
1735 1752
          if (label_index != -1)
1736 1753
            _node_index.insert(std::make_pair(tokens[label_index], n));
1737 1754
        } else {
1738 1755
          if (label_index == -1)
1739
            throw DataFormatError("Label map not found in file");
1756
            throw FormatError("Label map not found in file");
1740 1757
          typename std::map<std::string, Node>::iterator it =
1741 1758
            _node_index.find(tokens[label_index]);
1742 1759
          if (it == _node_index.end()) {
1743 1760
            std::ostringstream msg;
1744 1761
            msg << "Node with label not found: " << tokens[label_index];
1745
            throw DataFormatError(msg.str().c_str());
1762
            throw FormatError(msg.str());
1746 1763
          }
1747 1764
          n = it->second;
1748 1765
        }
1749 1766

	
1750 1767
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1751 1768
          _node_maps[i].second->set(n, tokens[map_index[i]]);
1752 1769
        }
1753 1770

	
1754 1771
      }
1755 1772
      if (readSuccess()) {
1756 1773
        line.putback(c);
1757 1774
      }
1758 1775
    }
1759 1776

	
1760 1777
    void readEdges() {
1761 1778

	
1762 1779
      std::vector<int> map_index(_edge_maps.size());
1763 1780
      int map_num, label_index;
1764 1781

	
1765 1782
      char c;
1766 1783
      if (!readLine() || !(line >> c) || c == '@') {
1767 1784
        if (readSuccess() && line) line.putback(c);
1768 1785
        if (!_edge_maps.empty())
1769
          throw DataFormatError("Cannot find map names");
1786
          throw FormatError("Cannot find map names");
1770 1787
        return;
1771 1788
      }
1772 1789
      line.putback(c);
1773 1790

	
1774 1791
      {
1775 1792
        std::map<std::string, int> maps;
1776 1793

	
1777 1794
        std::string map;
1778 1795
        int index = 0;
1779 1796
        while (_reader_bits::readToken(line, map)) {
1780 1797
          if (maps.find(map) != maps.end()) {
1781 1798
            std::ostringstream msg;
1782 1799
            msg << "Multiple occurence of edge map: " << map;
1783
            throw DataFormatError(msg.str().c_str());
1800
            throw FormatError(msg.str());
1784 1801
          }
1785 1802
          maps.insert(std::make_pair(map, index));
1786 1803
          ++index;
1787 1804
        }
1788 1805

	
1789 1806
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1790 1807
          std::map<std::string, int>::iterator jt =
1791 1808
            maps.find(_edge_maps[i].first);
1792 1809
          if (jt == maps.end()) {
1793 1810
            std::ostringstream msg;
1794 1811
            msg << "Map not found in file: " << _edge_maps[i].first;
1795
            throw DataFormatError(msg.str().c_str());
1812
            throw FormatError(msg.str());
1796 1813
          }
1797 1814
          map_index[i] = jt->second;
1798 1815
        }
1799 1816

	
1800 1817
        {
1801 1818
          std::map<std::string, int>::iterator jt = maps.find("label");
1802 1819
          if (jt != maps.end()) {
1803 1820
            label_index = jt->second;
1804 1821
          } else {
1805 1822
            label_index = -1;
1806 1823
          }
1807 1824
        }
1808 1825
        map_num = maps.size();
1809 1826
      }
1810 1827

	
1811 1828
      while (readLine() && line >> c && c != '@') {
1812 1829
        line.putback(c);
1813 1830

	
1814 1831
        std::string source_token;
1815 1832
        std::string target_token;
1816 1833

	
1817 1834
        if (!_reader_bits::readToken(line, source_token))
1818
          throw DataFormatError("Node u not found");
1835
          throw FormatError("Node u not found");
1819 1836

	
1820 1837
        if (!_reader_bits::readToken(line, target_token))
1821
          throw DataFormatError("Node v not found");
1838
          throw FormatError("Node v not found");
1822 1839

	
1823 1840
        std::vector<std::string> tokens(map_num);
1824 1841
        for (int i = 0; i < map_num; ++i) {
1825 1842
          if (!_reader_bits::readToken(line, tokens[i])) {
1826 1843
            std::ostringstream msg;
1827 1844
            msg << "Column not found (" << i + 1 << ")";
1828
            throw DataFormatError(msg.str().c_str());
1845
            throw FormatError(msg.str());
1829 1846
          }
1830 1847
        }
1831 1848
        if (line >> std::ws >> c)
1832
          throw DataFormatError("Extra character on the end of line");
1849
          throw FormatError("Extra character on the end of line");
1833 1850

	
1834 1851
        Edge e;
1835 1852
        if (!_use_edges) {
1836 1853

	
1837 1854
          typename NodeIndex::iterator it;
1838 1855

	
1839 1856
          it = _node_index.find(source_token);
1840 1857
          if (it == _node_index.end()) {
1841 1858
            std::ostringstream msg;
1842 1859
            msg << "Item not found: " << source_token;
1843
            throw DataFormatError(msg.str().c_str());
1860
            throw FormatError(msg.str());
1844 1861
          }
1845 1862
          Node source = it->second;
1846 1863

	
1847 1864
          it = _node_index.find(target_token);
1848 1865
          if (it == _node_index.end()) {
1849 1866
            std::ostringstream msg;
1850 1867
            msg << "Item not found: " << target_token;
1851
            throw DataFormatError(msg.str().c_str());
1868
            throw FormatError(msg.str());
1852 1869
          }
1853 1870
          Node target = it->second;
1854 1871

	
1855 1872
          e = _graph.addEdge(source, target);
1856 1873
          if (label_index != -1)
1857 1874
            _edge_index.insert(std::make_pair(tokens[label_index], e));
1858 1875
        } else {
1859 1876
          if (label_index == -1)
1860
            throw DataFormatError("Label map not found in file");
1877
            throw FormatError("Label map not found in file");
1861 1878
          typename std::map<std::string, Edge>::iterator it =
1862 1879
            _edge_index.find(tokens[label_index]);
1863 1880
          if (it == _edge_index.end()) {
1864 1881
            std::ostringstream msg;
1865 1882
            msg << "Edge with label not found: " << tokens[label_index];
1866
            throw DataFormatError(msg.str().c_str());
1883
            throw FormatError(msg.str());
1867 1884
          }
1868 1885
          e = it->second;
1869 1886
        }
1870 1887

	
1871 1888
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1872 1889
          _edge_maps[i].second->set(e, tokens[map_index[i]]);
1873 1890
        }
1874 1891

	
1875 1892
      }
1876 1893
      if (readSuccess()) {
1877 1894
        line.putback(c);
1878 1895
      }
1879 1896
    }
1880 1897

	
1881 1898
    void readAttributes() {
1882 1899

	
1883 1900
      std::set<std::string> read_attr;
1884 1901

	
1885 1902
      char c;
1886 1903
      while (readLine() && line >> c && c != '@') {
1887 1904
        line.putback(c);
1888 1905

	
1889 1906
        std::string attr, token;
1890 1907
        if (!_reader_bits::readToken(line, attr))
1891
          throw DataFormatError("Attribute name not found");
1908
          throw FormatError("Attribute name not found");
1892 1909
        if (!_reader_bits::readToken(line, token))
1893
          throw DataFormatError("Attribute value not found");
1910
          throw FormatError("Attribute value not found");
1894 1911
        if (line >> c)
1895
          throw DataFormatError("Extra character on the end of line");
1912
          throw FormatError("Extra character on the end of line");
1896 1913

	
1897 1914
        {
1898 1915
          std::set<std::string>::iterator it = read_attr.find(attr);
1899 1916
          if (it != read_attr.end()) {
1900 1917
            std::ostringstream msg;
1901 1918
            msg << "Multiple occurence of attribute " << attr;
1902
            throw DataFormatError(msg.str().c_str());
1919
            throw FormatError(msg.str());
1903 1920
          }
1904 1921
          read_attr.insert(attr);
1905 1922
        }
1906 1923

	
1907 1924
        {
1908 1925
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1909 1926
          while (it != _attributes.end() && it->first == attr) {
1910 1927
            it->second->set(token);
1911 1928
            ++it;
1912 1929
          }
1913 1930
        }
1914 1931

	
1915 1932
      }
1916 1933
      if (readSuccess()) {
1917 1934
        line.putback(c);
1918 1935
      }
1919 1936
      for (typename Attributes::iterator it = _attributes.begin();
1920 1937
           it != _attributes.end(); ++it) {
1921 1938
        if (read_attr.find(it->first) == read_attr.end()) {
1922 1939
          std::ostringstream msg;
1923 1940
          msg << "Attribute not found in file: " << it->first;
1924
          throw DataFormatError(msg.str().c_str());
1941
          throw FormatError(msg.str());
1925 1942
        }
1926 1943
      }
1927 1944
    }
1928 1945

	
1929 1946
  public:
1930 1947

	
1931 1948
    /// \name Execution of the reader
1932 1949
    /// @{
1933 1950

	
1934 1951
    /// \brief Start the batch processing
1935 1952
    ///
1936 1953
    /// This function starts the batch processing
1937 1954
    void run() {
1938 1955

	
1939 1956
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1940 1957

	
1941 1958
      bool nodes_done = _skip_nodes;
1942 1959
      bool edges_done = _skip_edges;
1943 1960
      bool attributes_done = false;
1944 1961

	
1945 1962
      line_num = 0;
1946 1963
      readLine();
1947 1964
      skipSection();
1948 1965

	
1949 1966
      while (readSuccess()) {
1950 1967
        try {
1951 1968
          char c;
1952 1969
          std::string section, caption;
1953 1970
          line >> c;
1954 1971
          _reader_bits::readToken(line, section);
1955 1972
          _reader_bits::readToken(line, caption);
1956 1973

	
1957 1974
          if (line >> c)
1958
            throw DataFormatError("Extra character on the end of line");
1975
            throw FormatError("Extra character on the end of line");
1959 1976

	
1960 1977
          if (section == "nodes" && !nodes_done) {
1961 1978
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1962 1979
              readNodes();
1963 1980
              nodes_done = true;
1964 1981
            }
1965 1982
          } else if ((section == "edges" || section == "arcs") &&
1966 1983
                     !edges_done) {
1967 1984
            if (_edges_caption.empty() || _edges_caption == caption) {
1968 1985
              readEdges();
1969 1986
              edges_done = true;
1970 1987
            }
1971 1988
          } else if (section == "attributes" && !attributes_done) {
1972 1989
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1973 1990
              readAttributes();
1974 1991
              attributes_done = true;
1975 1992
            }
1976 1993
          } else {
1977 1994
            readLine();
1978 1995
            skipSection();
1979 1996
          }
1980
        } catch (DataFormatError& error) {
1997
        } catch (FormatError& error) {
1981 1998
          error.line(line_num);
1999
          error.file(_filename);
1982 2000
          throw;
1983 2001
        }
1984 2002
      }
1985 2003

	
1986 2004
      if (!nodes_done) {
1987
        throw DataFormatError("Section @nodes not found");
2005
        throw FormatError("Section @nodes not found");
1988 2006
      }
1989 2007

	
1990 2008
      if (!edges_done) {
1991
        throw DataFormatError("Section @edges not found");
2009
        throw FormatError("Section @edges not found");
1992 2010
      }
1993 2011

	
1994 2012
      if (!attributes_done && !_attributes.empty()) {
1995
        throw DataFormatError("Section @attributes not found");
2013
        throw FormatError("Section @attributes not found");
1996 2014
      }
1997 2015

	
1998 2016
    }
1999 2017

	
2000 2018
    /// @}
2001 2019

	
2002 2020
  };
2003 2021

	
2004 2022
  /// \brief Return a \ref GraphReader class
2005 2023
  ///
2006 2024
  /// This function just returns a \ref GraphReader class.
2007 2025
  /// \relates GraphReader
2008 2026
  template <typename Graph>
2009 2027
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph) {
2010 2028
    GraphReader<Graph> tmp(is, graph);
2011 2029
    return tmp;
2012 2030
  }
2013 2031

	
2014 2032
  /// \brief Return a \ref GraphReader class
2015 2033
  ///
2016 2034
  /// This function just returns a \ref GraphReader class.
2017 2035
  /// \relates GraphReader
2018 2036
  template <typename Graph>
2019 2037
  GraphReader<Graph> graphReader(const std::string& fn,
2020 2038
                                       Graph& graph) {
2021 2039
    GraphReader<Graph> tmp(fn, graph);
2022 2040
    return tmp;
2023 2041
  }
2024 2042

	
2025 2043
  /// \brief Return a \ref GraphReader class
2026 2044
  ///
2027 2045
  /// This function just returns a \ref GraphReader class.
2028 2046
  /// \relates GraphReader
2029 2047
  template <typename Graph>
2030 2048
  GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
2031 2049
    GraphReader<Graph> tmp(fn, graph);
2032 2050
    return tmp;
2033 2051
  }
2034 2052

	
2035 2053
  class SectionReader;
2036 2054

	
2037 2055
  SectionReader sectionReader(std::istream& is);
2038 2056
  SectionReader sectionReader(const std::string& fn);
2039 2057
  SectionReader sectionReader(const char* fn);
2040 2058

	
2041 2059
  /// \ingroup lemon_io
2042 2060
  ///
2043 2061
  /// \brief Section reader class
2044 2062
  ///
2045 2063
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
2046 2064
  /// which contain any data in arbitrary format. Such sections can be
2047 2065
  /// read with this class. A reading rule can be added to the class
2048 2066
  /// with two different functions. With the \c sectionLines() function a
2049 2067
  /// functor can process the section line-by-line, while with the \c
2050 2068
  /// sectionStream() member the section can be read from an input
2051 2069
  /// stream.
2052 2070
  class SectionReader {
2053 2071
  private:
2054 2072

	
2055 2073
    std::istream* _is;
2056 2074
    bool local_is;
2075
    std::string _filename;
2057 2076

	
2058 2077
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2059 2078
    Sections _sections;
2060 2079

	
2061 2080
    int line_num;
2062 2081
    std::istringstream line;
2063 2082

	
2064 2083
  public:
2065 2084

	
2066 2085
    /// \brief Constructor
2067 2086
    ///
2068 2087
    /// Construct a section reader, which reads from the given input
2069 2088
    /// stream.
2070 2089
    SectionReader(std::istream& is)
2071 2090
      : _is(&is), local_is(false) {}
2072 2091

	
2073 2092
    /// \brief Constructor
2074 2093
    ///
2075 2094
    /// Construct a section reader, which reads from the given file.
2076 2095
    SectionReader(const std::string& fn)
2077
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2096
      : _is(new std::ifstream(fn.c_str())), local_is(true),
2097
        _filename(fn) {
2098
      if (!(*_is)) throw IoError(fn, "Cannot open file");
2099
    }
2078 2100

	
2079 2101
    /// \brief Constructor
2080 2102
    ///
2081 2103
    /// Construct a section reader, which reads from the given file.
2082 2104
    SectionReader(const char* fn)
2083
      : _is(new std::ifstream(fn)), local_is(true) {}
2105
      : _is(new std::ifstream(fn)), local_is(true),
2106
        _filename(fn) {
2107
      if (!(*_is)) throw IoError(fn, "Cannot open file");
2108
    }
2084 2109

	
2085 2110
    /// \brief Destructor
2086 2111
    ~SectionReader() {
2087 2112
      for (Sections::iterator it = _sections.begin();
2088 2113
           it != _sections.end(); ++it) {
2089 2114
        delete it->second;
2090 2115
      }
2091 2116

	
2092 2117
      if (local_is) {
2093 2118
        delete _is;
2094 2119
      }
2095 2120

	
2096 2121
    }
2097 2122

	
2098 2123
  private:
2099 2124

	
2100 2125
    friend SectionReader sectionReader(std::istream& is);
2101 2126
    friend SectionReader sectionReader(const std::string& fn);
2102 2127
    friend SectionReader sectionReader(const char* fn);
2103 2128

	
2104 2129
    SectionReader(SectionReader& other)
2105 2130
      : _is(other._is), local_is(other.local_is) {
2106 2131

	
2107 2132
      other._is = 0;
2108 2133
      other.local_is = false;
2109 2134

	
2110 2135
      _sections.swap(other._sections);
2111 2136
    }
2112 2137

	
2113 2138
    SectionReader& operator=(const SectionReader&);
2114 2139

	
2115 2140
  public:
2116 2141

	
2117 2142
    /// \name Section readers
2118 2143
    /// @{
2119 2144

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

	
2164 2189

	
2165 2190
    /// \brief Add a section processor with stream oriented reading
2166 2191
    ///
2167 2192
    /// The first parameter is the type of the section, the second is
2168 2193
    /// a functor, which takes an \c std::istream& and an \c int&
2169 2194
    /// parameter, the latter regard to the line number of stream. The
2170 2195
    /// functor can read the input while the section go on, and the
2171 2196
    /// line number should be modified accordingly.
2172 2197
    template <typename Functor>
2173 2198
    SectionReader& sectionStream(const std::string& type, Functor functor) {
2174 2199
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2175 2200
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2176 2201
                   "Multiple reading of section.");
2177 2202
      _sections.insert(std::make_pair(type,
2178 2203
         new _reader_bits::StreamSection<Functor>(functor)));
2179 2204
      return *this;
2180 2205
    }
2181 2206

	
2182 2207
    /// @}
2183 2208

	
2184 2209
  private:
2185 2210

	
2186 2211
    bool readLine() {
2187 2212
      std::string str;
2188 2213
      while(++line_num, std::getline(*_is, str)) {
2189 2214
        line.clear(); line.str(str);
2190 2215
        char c;
2191 2216
        if (line >> std::ws >> c && c != '#') {
2192 2217
          line.putback(c);
2193 2218
          return true;
2194 2219
        }
2195 2220
      }
2196 2221
      return false;
2197 2222
    }
2198 2223

	
2199 2224
    bool readSuccess() {
2200 2225
      return static_cast<bool>(*_is);
2201 2226
    }
2202 2227

	
2203 2228
    void skipSection() {
2204 2229
      char c;
2205 2230
      while (readSuccess() && line >> c && c != '@') {
2206 2231
        readLine();
2207 2232
      }
2208 2233
      line.putback(c);
2209 2234
    }
2210 2235

	
2211 2236
  public:
2212 2237

	
2213 2238

	
2214 2239
    /// \name Execution of the reader
2215 2240
    /// @{
2216 2241

	
2217 2242
    /// \brief Start the batch processing
2218 2243
    ///
2219 2244
    /// This function starts the batch processing.
2220 2245
    void run() {
2221 2246

	
2222 2247
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2223 2248

	
2224 2249
      std::set<std::string> extra_sections;
2225 2250

	
2226 2251
      line_num = 0;
2227 2252
      readLine();
2228 2253
      skipSection();
2229 2254

	
2230 2255
      while (readSuccess()) {
2231 2256
        try {
2232 2257
          char c;
2233 2258
          std::string section, caption;
2234 2259
          line >> c;
2235 2260
          _reader_bits::readToken(line, section);
2236 2261
          _reader_bits::readToken(line, caption);
2237 2262

	
2238 2263
          if (line >> c)
2239
            throw DataFormatError("Extra character on the end of line");
2264
            throw FormatError("Extra character on the end of line");
2240 2265

	
2241 2266
          if (extra_sections.find(section) != extra_sections.end()) {
2242 2267
            std::ostringstream msg;
2243 2268
            msg << "Multiple occurence of section " << section;
2244
            throw DataFormatError(msg.str().c_str());
2269
            throw FormatError(msg.str());
2245 2270
          }
2246 2271
          Sections::iterator it = _sections.find(section);
2247 2272
          if (it != _sections.end()) {
2248 2273
            extra_sections.insert(section);
2249 2274
            it->second->process(*_is, line_num);
2250 2275
          }
2251 2276
          readLine();
2252 2277
          skipSection();
2253
        } catch (DataFormatError& error) {
2278
        } catch (FormatError& error) {
2254 2279
          error.line(line_num);
2280
          error.file(_filename);
2255 2281
          throw;
2256 2282
        }
2257 2283
      }
2258 2284
      for (Sections::iterator it = _sections.begin();
2259 2285
           it != _sections.end(); ++it) {
2260 2286
        if (extra_sections.find(it->first) == extra_sections.end()) {
2261 2287
          std::ostringstream os;
2262 2288
          os << "Cannot find section: " << it->first;
2263
          throw DataFormatError(os.str().c_str());
2289
          throw FormatError(os.str());
2264 2290
        }
2265 2291
      }
2266 2292
    }
2267 2293

	
2268 2294
    /// @}
2269 2295

	
2270 2296
  };
2271 2297

	
2272 2298
  /// \brief Return a \ref SectionReader class
2273 2299
  ///
2274 2300
  /// This function just returns a \ref SectionReader class.
2275 2301
  /// \relates SectionReader
2276 2302
  inline SectionReader sectionReader(std::istream& is) {
2277 2303
    SectionReader tmp(is);
2278 2304
    return tmp;
2279 2305
  }
2280 2306

	
2281 2307
  /// \brief Return a \ref SectionReader class
2282 2308
  ///
2283 2309
  /// This function just returns a \ref SectionReader class.
2284 2310
  /// \relates SectionReader
2285 2311
  inline SectionReader sectionReader(const std::string& fn) {
2286 2312
    SectionReader tmp(fn);
2287 2313
    return tmp;
2288 2314
  }
2289 2315

	
2290 2316
  /// \brief Return a \ref SectionReader class
2291 2317
  ///
2292 2318
  /// This function just returns a \ref SectionReader class.
2293 2319
  /// \relates SectionReader
2294 2320
  inline SectionReader sectionReader(const char* fn) {
2295 2321
    SectionReader tmp(fn);
2296 2322
    return tmp;
2297 2323
  }
2298 2324

	
2299 2325
  /// \ingroup lemon_io
2300 2326
  ///
2301 2327
  /// \brief Reader for the contents of the \ref lgf-format "LGF" file
2302 2328
  ///
2303 2329
  /// This class can be used to read the sections, the map names and
2304 2330
  /// the attributes from a file. Usually, the LEMON programs know
2305 2331
  /// that, which type of graph, which maps and which attributes
2306 2332
  /// should be read from a file, but in general tools (like glemon)
2307 2333
  /// the contents of an LGF file should be guessed somehow. This class
2308 2334
  /// reads the graph and stores the appropriate information for
2309 2335
  /// reading the graph.
2310 2336
  ///
2311 2337
  ///\code
2312 2338
  /// LgfContents contents("graph.lgf");
2313 2339
  /// contents.run();
2314 2340
  ///
2315 2341
  /// // Does it contain any node section and arc section?
2316 2342
  /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
2317 2343
  ///   std::cerr << "Failure, cannot find graph." << std::endl;
2318 2344
  ///   return -1;
2319 2345
  /// }
2320 2346
  /// std::cout << "The name of the default node section: "
2321 2347
  ///           << contents.nodeSection(0) << std::endl;
2322 2348
  /// std::cout << "The number of the arc maps: "
2323 2349
  ///           << contents.arcMaps(0).size() << std::endl;
2324 2350
  /// std::cout << "The name of second arc map: "
2325 2351
  ///           << contents.arcMaps(0)[1] << std::endl;
2326 2352
  ///\endcode
2327 2353
  class LgfContents {
2328 2354
  private:
2329 2355

	
2330 2356
    std::istream* _is;
2331 2357
    bool local_is;
2332 2358

	
2333 2359
    std::vector<std::string> _node_sections;
2334 2360
    std::vector<std::string> _edge_sections;
2335 2361
    std::vector<std::string> _attribute_sections;
2336 2362
    std::vector<std::string> _extra_sections;
2337 2363

	
2338 2364
    std::vector<bool> _arc_sections;
2339 2365

	
2340 2366
    std::vector<std::vector<std::string> > _node_maps;
2341 2367
    std::vector<std::vector<std::string> > _edge_maps;
2342 2368

	
2343 2369
    std::vector<std::vector<std::string> > _attributes;
2344 2370

	
2345 2371

	
2346 2372
    int line_num;
2347 2373
    std::istringstream line;
2348 2374

	
2349 2375
  public:
2350 2376

	
2351 2377
    /// \brief Constructor
2352 2378
    ///
2353 2379
    /// Construct an \e LGF contents reader, which reads from the given
2354 2380
    /// input stream.
2355 2381
    LgfContents(std::istream& is)
2356 2382
      : _is(&is), local_is(false) {}
2357 2383

	
2358 2384
    /// \brief Constructor
2359 2385
    ///
2360 2386
    /// Construct an \e LGF contents reader, which reads from the given
2361 2387
    /// file.
2362 2388
    LgfContents(const std::string& fn)
2363
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2389
      : _is(new std::ifstream(fn.c_str())), local_is(true) {
2390
      if (!(*_is)) throw IoError(fn, "Cannot open file");
2391
    }
2364 2392

	
2365 2393
    /// \brief Constructor
2366 2394
    ///
2367 2395
    /// Construct an \e LGF contents reader, which reads from the given
2368 2396
    /// file.
2369 2397
    LgfContents(const char* fn)
2370
      : _is(new std::ifstream(fn)), local_is(true) {}
2398
      : _is(new std::ifstream(fn)), local_is(true) {
2399
      if (!(*_is)) throw IoError(fn, "Cannot open file");
2400
    }
2371 2401

	
2372 2402
    /// \brief Destructor
2373 2403
    ~LgfContents() {
2374 2404
      if (local_is) delete _is;
2375 2405
    }
2376 2406

	
2377 2407
  private:
2378 2408

	
2379 2409
    LgfContents(const LgfContents&);
2380 2410
    LgfContents& operator=(const LgfContents&);
2381 2411

	
2382 2412
  public:
2383 2413

	
2384 2414

	
2385 2415
    /// \name Node sections
2386 2416
    /// @{
2387 2417

	
2388 2418
    /// \brief Gives back the number of node sections in the file.
2389 2419
    ///
2390 2420
    /// Gives back the number of node sections in the file.
2391 2421
    int nodeSectionNum() const {
2392 2422
      return _node_sections.size();
2393 2423
    }
2394 2424

	
2395 2425
    /// \brief Returns the node section name at the given position.
2396 2426
    ///
2397 2427
    /// Returns the node section name at the given position.
2398 2428
    const std::string& nodeSection(int i) const {
2399 2429
      return _node_sections[i];
2400 2430
    }
2401 2431

	
2402 2432
    /// \brief Gives back the node maps for the given section.
2403 2433
    ///
2404 2434
    /// Gives back the node maps for the given section.
2405 2435
    const std::vector<std::string>& nodeMapNames(int i) const {
2406 2436
      return _node_maps[i];
2407 2437
    }
2408 2438

	
2409 2439
    /// @}
2410 2440

	
2411 2441
    /// \name Arc/Edge sections
2412 2442
    /// @{
2413 2443

	
2414 2444
    /// \brief Gives back the number of arc/edge sections in the file.
2415 2445
    ///
2416 2446
    /// Gives back the number of arc/edge sections in the file.
2417 2447
    /// \note It is synonym of \c edgeSectionNum().
2418 2448
    int arcSectionNum() const {
2419 2449
      return _edge_sections.size();
2420 2450
    }
2421 2451

	
2422 2452
    /// \brief Returns the arc/edge section name at the given position.
2423 2453
    ///
2424 2454
    /// Returns the arc/edge section name at the given position.
2425 2455
    /// \note It is synonym of \c edgeSection().
2426 2456
    const std::string& arcSection(int i) const {
2427 2457
      return _edge_sections[i];
2428 2458
    }
2429 2459

	
2430 2460
    /// \brief Gives back the arc/edge maps for the given section.
2431 2461
    ///
2432 2462
    /// Gives back the arc/edge maps for the given section.
2433 2463
    /// \note It is synonym of \c edgeMapNames().
2434 2464
    const std::vector<std::string>& arcMapNames(int i) const {
2435 2465
      return _edge_maps[i];
2436 2466
    }
2437 2467

	
2438 2468
    /// @}
2439 2469

	
2440 2470
    /// \name Synonyms
2441 2471
    /// @{
2442 2472

	
2443 2473
    /// \brief Gives back the number of arc/edge sections in the file.
2444 2474
    ///
2445 2475
    /// Gives back the number of arc/edge sections in the file.
2446 2476
    /// \note It is synonym of \c arcSectionNum().
2447 2477
    int edgeSectionNum() const {
2448 2478
      return _edge_sections.size();
2449 2479
    }
2450 2480

	
2451 2481
    /// \brief Returns the section name at the given position.
2452 2482
    ///
2453 2483
    /// Returns the section name at the given position.
2454 2484
    /// \note It is synonym of \c arcSection().
2455 2485
    const std::string& edgeSection(int i) const {
2456 2486
      return _edge_sections[i];
2457 2487
    }
2458 2488

	
2459 2489
    /// \brief Gives back the edge maps for the given section.
2460 2490
    ///
2461 2491
    /// Gives back the edge maps for the given section.
2462 2492
    /// \note It is synonym of \c arcMapNames().
2463 2493
    const std::vector<std::string>& edgeMapNames(int i) const {
2464 2494
      return _edge_maps[i];
2465 2495
    }
2466 2496

	
2467 2497
    /// @}
2468 2498

	
2469 2499
    /// \name Attribute sections
2470 2500
    /// @{
2471 2501

	
2472 2502
    /// \brief Gives back the number of attribute sections in the file.
2473 2503
    ///
2474 2504
    /// Gives back the number of attribute sections in the file.
2475 2505
    int attributeSectionNum() const {
2476 2506
      return _attribute_sections.size();
2477 2507
    }
2478 2508

	
2479 2509
    /// \brief Returns the attribute section name at the given position.
2480 2510
    ///
2481 2511
    /// Returns the attribute section name at the given position.
2482 2512
    const std::string& attributeSectionNames(int i) const {
2483 2513
      return _attribute_sections[i];
2484 2514
    }
2485 2515

	
2486 2516
    /// \brief Gives back the attributes for the given section.
2487 2517
    ///
2488 2518
    /// Gives back the attributes for the given section.
2489 2519
    const std::vector<std::string>& attributes(int i) const {
2490 2520
      return _attributes[i];
2491 2521
    }
2492 2522

	
2493 2523
    /// @}
2494 2524

	
2495 2525
    /// \name Extra sections
2496 2526
    /// @{
2497 2527

	
2498 2528
    /// \brief Gives back the number of extra sections in the file.
2499 2529
    ///
2500 2530
    /// Gives back the number of extra sections in the file.
2501 2531
    int extraSectionNum() const {
2502 2532
      return _extra_sections.size();
2503 2533
    }
2504 2534

	
2505 2535
    /// \brief Returns the extra section type at the given position.
2506 2536
    ///
2507 2537
    /// Returns the section type at the given position.
2508 2538
    const std::string& extraSection(int i) const {
2509 2539
      return _extra_sections[i];
2510 2540
    }
2511 2541

	
2512 2542
    /// @}
2513 2543

	
2514 2544
  private:
2515 2545

	
2516 2546
    bool readLine() {
2517 2547
      std::string str;
2518 2548
      while(++line_num, std::getline(*_is, str)) {
2519 2549
        line.clear(); line.str(str);
2520 2550
        char c;
2521 2551
        if (line >> std::ws >> c && c != '#') {
2522 2552
          line.putback(c);
2523 2553
          return true;
2524 2554
        }
2525 2555
      }
2526 2556
      return false;
2527 2557
    }
2528 2558

	
2529 2559
    bool readSuccess() {
2530 2560
      return static_cast<bool>(*_is);
2531 2561
    }
2532 2562

	
2533 2563
    void skipSection() {
2534 2564
      char c;
2535 2565
      while (readSuccess() && line >> c && c != '@') {
2536 2566
        readLine();
2537 2567
      }
2538 2568
      line.putback(c);
2539 2569
    }
2540 2570

	
2541 2571
    void readMaps(std::vector<std::string>& maps) {
2542 2572
      char c;
2543 2573
      if (!readLine() || !(line >> c) || c == '@') {
2544 2574
        if (readSuccess() && line) line.putback(c);
2545 2575
        return;
2546 2576
      }
2547 2577
      line.putback(c);
2548 2578
      std::string map;
2549 2579
      while (_reader_bits::readToken(line, map)) {
2550 2580
        maps.push_back(map);
2551 2581
      }
2552 2582
    }
2553 2583

	
2554 2584
    void readAttributes(std::vector<std::string>& attrs) {
2555 2585
      readLine();
2556 2586
      char c;
2557 2587
      while (readSuccess() && line >> c && c != '@') {
2558 2588
        line.putback(c);
2559 2589
        std::string attr;
2560 2590
        _reader_bits::readToken(line, attr);
2561 2591
        attrs.push_back(attr);
2562 2592
        readLine();
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

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

	
23 23

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

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

	
31 31
#include <algorithm>
32 32

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

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

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

	
43 43
namespace lemon {
44 44

	
45 45
  namespace _writer_bits {
46 46

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
320 320
      Functor _functor;
321 321

	
322 322
    public:
323 323

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

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

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

	
337 337
      Functor _functor;
338 338

	
339 339
    public:
340 340

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

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

	
349 349
  }
350 350

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

	
354 354
  template <typename Digraph>
355 355
  DigraphWriter<Digraph> digraphWriter(std::ostream& os,
356 356
                                       const Digraph& digraph);
357 357

	
358 358
  template <typename Digraph>
359 359
  DigraphWriter<Digraph> digraphWriter(const std::string& fn,
360 360
                                       const Digraph& digraph);
361 361

	
362 362
  template <typename Digraph>
363 363
  DigraphWriter<Digraph> digraphWriter(const char *fn,
364 364
                                       const Digraph& digraph);
365 365

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

	
414 414
    typedef _Digraph Digraph;
415 415
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
416 416

	
417 417
  private:
418 418

	
419 419

	
420 420
    std::ostream* _os;
421 421
    bool local_os;
422 422

	
423 423
    const Digraph& _digraph;
424 424

	
425 425
    std::string _nodes_caption;
426 426
    std::string _arcs_caption;
427 427
    std::string _attributes_caption;
428 428

	
429 429
    typedef std::map<Node, std::string> NodeIndex;
430 430
    NodeIndex _node_index;
431 431
    typedef std::map<Arc, std::string> ArcIndex;
432 432
    ArcIndex _arc_index;
433 433

	
434 434
    typedef std::vector<std::pair<std::string,
435 435
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
436 436
    NodeMaps _node_maps;
437 437

	
438 438
    typedef std::vector<std::pair<std::string,
439 439
      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
440 440
    ArcMaps _arc_maps;
441 441

	
442 442
    typedef std::vector<std::pair<std::string,
443 443
      _writer_bits::ValueStorageBase*> > Attributes;
444 444
    Attributes _attributes;
445 445

	
446 446
    bool _skip_nodes;
447 447
    bool _skip_arcs;
448 448

	
449 449
  public:
450 450

	
451 451
    /// \brief Constructor
452 452
    ///
453 453
    /// Construct a directed graph writer, which writes to the given
454 454
    /// output stream.
455 455
    DigraphWriter(std::ostream& is, const Digraph& digraph)
456 456
      : _os(&is), local_os(false), _digraph(digraph),
457 457
        _skip_nodes(false), _skip_arcs(false) {}
458 458

	
459 459
    /// \brief Constructor
460 460
    ///
461 461
    /// Construct a directed graph writer, which writes to the given
462 462
    /// output file.
463 463
    DigraphWriter(const std::string& fn, const Digraph& digraph)
464 464
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
465
        _skip_nodes(false), _skip_arcs(false) {}
465
        _skip_nodes(false), _skip_arcs(false) {
466
      if (!(*_os)) throw IoError(fn, "Cannot write file");
467
    }
466 468

	
467 469
    /// \brief Constructor
468 470
    ///
469 471
    /// Construct a directed graph writer, which writes to the given
470 472
    /// output file.
471 473
    DigraphWriter(const char* fn, const Digraph& digraph)
472 474
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
473
        _skip_nodes(false), _skip_arcs(false) {}
475
        _skip_nodes(false), _skip_arcs(false) {
476
      if (!(*_os)) throw IoError(fn, "Cannot write file");
477
    }
474 478

	
475 479
    /// \brief Destructor
476 480
    ~DigraphWriter() {
477 481
      for (typename NodeMaps::iterator it = _node_maps.begin();
478 482
           it != _node_maps.end(); ++it) {
479 483
        delete it->second;
480 484
      }
481 485

	
482 486
      for (typename ArcMaps::iterator it = _arc_maps.begin();
483 487
           it != _arc_maps.end(); ++it) {
484 488
        delete it->second;
485 489
      }
486 490

	
487 491
      for (typename Attributes::iterator it = _attributes.begin();
488 492
           it != _attributes.end(); ++it) {
489 493
        delete it->second;
490 494
      }
491 495

	
492 496
      if (local_os) {
493 497
        delete _os;
494 498
      }
495 499
    }
496 500

	
497 501
  private:
498 502

	
499 503
    friend DigraphWriter<Digraph> digraphWriter<>(std::ostream& os,
500 504
                                                  const Digraph& digraph);
501 505
    friend DigraphWriter<Digraph> digraphWriter<>(const std::string& fn,
502 506
                                                  const Digraph& digraph);
503 507
    friend DigraphWriter<Digraph> digraphWriter<>(const char *fn,
504 508
                                                  const Digraph& digraph);
505 509

	
506 510
    DigraphWriter(DigraphWriter& other)
507 511
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
508 512
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
509 513

	
510 514
      other._os = 0;
511 515
      other.local_os = false;
512 516

	
513 517
      _node_index.swap(other._node_index);
514 518
      _arc_index.swap(other._arc_index);
515 519

	
516 520
      _node_maps.swap(other._node_maps);
517 521
      _arc_maps.swap(other._arc_maps);
518 522
      _attributes.swap(other._attributes);
519 523

	
520 524
      _nodes_caption = other._nodes_caption;
521 525
      _arcs_caption = other._arcs_caption;
522 526
      _attributes_caption = other._attributes_caption;
523 527
    }
524 528

	
525 529
    DigraphWriter& operator=(const DigraphWriter&);
526 530

	
527 531
  public:
528 532

	
529 533
    /// \name Writing rules
530 534
    /// @{
531 535

	
532 536
    /// \brief Node map writing rule
533 537
    ///
534 538
    /// Add a node map writing rule to the writer.
535 539
    template <typename Map>
536 540
    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
537 541
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
538 542
      _writer_bits::MapStorageBase<Node>* storage =
539 543
        new _writer_bits::MapStorage<Node, Map>(map);
540 544
      _node_maps.push_back(std::make_pair(caption, storage));
541 545
      return *this;
542 546
    }
543 547

	
544 548
    /// \brief Node map writing rule
545 549
    ///
546 550
    /// Add a node map writing rule with specialized converter to the
547 551
    /// writer.
548 552
    template <typename Map, typename Converter>
549 553
    DigraphWriter& nodeMap(const std::string& caption, const Map& map,
550 554
                           const Converter& converter = Converter()) {
551 555
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
552 556
      _writer_bits::MapStorageBase<Node>* storage =
553 557
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
554 558
      _node_maps.push_back(std::make_pair(caption, storage));
555 559
      return *this;
556 560
    }
557 561

	
558 562
    /// \brief Arc map writing rule
559 563
    ///
560 564
    /// Add an arc map writing rule to the writer.
561 565
    template <typename Map>
562 566
    DigraphWriter& arcMap(const std::string& caption, const Map& map) {
563 567
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
564 568
      _writer_bits::MapStorageBase<Arc>* storage =
565 569
        new _writer_bits::MapStorage<Arc, Map>(map);
566 570
      _arc_maps.push_back(std::make_pair(caption, storage));
567 571
      return *this;
568 572
    }
569 573

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

	
584 588
    /// \brief Attribute writing rule
585 589
    ///
586 590
    /// Add an attribute writing rule to the writer.
587 591
    template <typename Value>
588 592
    DigraphWriter& attribute(const std::string& caption, const Value& value) {
589 593
      _writer_bits::ValueStorageBase* storage =
590 594
        new _writer_bits::ValueStorage<Value>(value);
591 595
      _attributes.push_back(std::make_pair(caption, storage));
592 596
      return *this;
593 597
    }
594 598

	
595 599
    /// \brief Attribute writing rule
596 600
    ///
597 601
    /// Add an attribute writing rule with specialized converter to the
598 602
    /// writer.
599 603
    template <typename Value, typename Converter>
600 604
    DigraphWriter& attribute(const std::string& caption, const Value& value,
601 605
                             const Converter& converter = Converter()) {
602 606
      _writer_bits::ValueStorageBase* storage =
603 607
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
604 608
      _attributes.push_back(std::make_pair(caption, storage));
605 609
      return *this;
606 610
    }
607 611

	
608 612
    /// \brief Node writing rule
609 613
    ///
610 614
    /// Add a node writing rule to the writer.
611 615
    DigraphWriter& node(const std::string& caption, const Node& node) {
612 616
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
613 617
      Converter converter(_node_index);
614 618
      _writer_bits::ValueStorageBase* storage =
615 619
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
616 620
      _attributes.push_back(std::make_pair(caption, storage));
617 621
      return *this;
618 622
    }
619 623

	
620 624
    /// \brief Arc writing rule
621 625
    ///
622 626
    /// Add an arc writing rule to writer.
623 627
    DigraphWriter& arc(const std::string& caption, const Arc& arc) {
624 628
      typedef _writer_bits::MapLookUpConverter<Arc> Converter;
625 629
      Converter converter(_arc_index);
626 630
      _writer_bits::ValueStorageBase* storage =
627 631
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
628 632
      _attributes.push_back(std::make_pair(caption, storage));
629 633
      return *this;
630 634
    }
631 635

	
632 636
    /// \name Section captions
633 637
    /// @{
634 638

	
635 639
    /// \brief Add an additional caption to the \c \@nodes section
636 640
    ///
637 641
    /// Add an additional caption to the \c \@nodes section.
638 642
    DigraphWriter& nodes(const std::string& caption) {
639 643
      _nodes_caption = caption;
640 644
      return *this;
641 645
    }
642 646

	
643 647
    /// \brief Add an additional caption to the \c \@arcs section
644 648
    ///
645 649
    /// Add an additional caption to the \c \@arcs section.
646 650
    DigraphWriter& arcs(const std::string& caption) {
647 651
      _arcs_caption = caption;
648 652
      return *this;
649 653
    }
650 654

	
651 655
    /// \brief Add an additional caption to the \c \@attributes section
652 656
    ///
653 657
    /// Add an additional caption to the \c \@attributes section.
654 658
    DigraphWriter& attributes(const std::string& caption) {
655 659
      _attributes_caption = caption;
656 660
      return *this;
657 661
    }
658 662

	
659 663
    /// \name Skipping section
660 664
    /// @{
661 665

	
662 666
    /// \brief Skip writing the node set
663 667
    ///
664 668
    /// The \c \@nodes section will not be written to the stream.
665 669
    DigraphWriter& skipNodes() {
... ...
@@ -829,393 +833,397 @@
829 833
          *_os << '\t';
830 834
        }
831 835
        *_os << std::endl;
832 836
      }
833 837
    }
834 838

	
835 839
    void createArcIndex() {
836 840
      _writer_bits::MapStorageBase<Arc>* label = 0;
837 841
      for (typename ArcMaps::iterator it = _arc_maps.begin();
838 842
           it != _arc_maps.end(); ++it) {
839 843
        if (it->first == "label") {
840 844
          label = it->second;
841 845
          break;
842 846
        }
843 847
      }
844 848

	
845 849
      if (label == 0) {
846 850
        for (ArcIt a(_digraph); a != INVALID; ++a) {
847 851
          std::ostringstream os;
848 852
          os << _digraph.id(a);
849 853
          _arc_index.insert(std::make_pair(a, os.str()));
850 854
        }
851 855
      } else {
852 856
        for (ArcIt a(_digraph); a != INVALID; ++a) {
853 857
          std::string value = label->get(a);
854 858
          _arc_index.insert(std::make_pair(a, value));
855 859
        }
856 860
      }
857 861
    }
858 862

	
859 863
    void writeAttributes() {
860 864
      if (_attributes.empty()) return;
861 865
      *_os << "@attributes";
862 866
      if (!_attributes_caption.empty()) {
863 867
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
864 868
      }
865 869
      *_os << std::endl;
866 870
      for (typename Attributes::iterator it = _attributes.begin();
867 871
           it != _attributes.end(); ++it) {
868 872
        _writer_bits::writeToken(*_os, it->first) << ' ';
869 873
        _writer_bits::writeToken(*_os, it->second->get());
870 874
        *_os << std::endl;
871 875
      }
872 876
    }
873 877

	
874 878
  public:
875 879

	
876 880
    /// \name Execution of the writer
877 881
    /// @{
878 882

	
879 883
    /// \brief Start the batch processing
880 884
    ///
881 885
    /// This function starts the batch processing.
882 886
    void run() {
883 887
      if (!_skip_nodes) {
884 888
        writeNodes();
885 889
      } else {
886 890
        createNodeIndex();
887 891
      }
888 892
      if (!_skip_arcs) {
889 893
        writeArcs();
890 894
      } else {
891 895
        createArcIndex();
892 896
      }
893 897
      writeAttributes();
894 898
    }
895 899

	
896 900
    /// \brief Give back the stream of the writer
897 901
    ///
898 902
    /// Give back the stream of the writer.
899 903
    std::ostream& ostream() {
900 904
      return *_os;
901 905
    }
902 906

	
903 907
    /// @}
904 908
  };
905 909

	
906 910
  /// \brief Return a \ref DigraphWriter class
907 911
  ///
908 912
  /// This function just returns a \ref DigraphWriter class.
909 913
  /// \relates DigraphWriter
910 914
  template <typename Digraph>
911 915
  DigraphWriter<Digraph> digraphWriter(std::ostream& os,
912 916
                                       const Digraph& digraph) {
913 917
    DigraphWriter<Digraph> tmp(os, digraph);
914 918
    return tmp;
915 919
  }
916 920

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

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

	
939 943
  template <typename Graph>
940 944
  class GraphWriter;
941 945

	
942 946
  template <typename Graph>
943 947
  GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph);
944 948

	
945 949
  template <typename Graph>
946 950
  GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph);
947 951

	
948 952
  template <typename Graph>
949 953
  GraphWriter<Graph> graphWriter(const char *fn, const Graph& graph);
950 954

	
951 955
  /// \ingroup lemon_io
952 956
  ///
953 957
  /// \brief \ref lgf-format "LGF" writer for directed graphs
954 958
  ///
955 959
  /// This utility writes an \ref lgf-format "LGF" file.
956 960
  ///
957 961
  /// It can be used almost the same way as \c DigraphWriter.
958 962
  /// The only difference is that this class can handle edges and
959 963
  /// edge maps as well as arcs and arc maps.
960 964
  ///
961 965
  /// The arc maps are written into the file as two columns, the
962 966
  /// caption of the columns are the name of the map prefixed with \c
963 967
  /// '+' and \c '-'. The arcs are written into the \c \@attributes
964 968
  /// section as a \c '+' or a \c '-' prefix (depends on the direction
965 969
  /// of the arc) and the label of corresponding edge.
966 970
  template <typename _Graph>
967 971
  class GraphWriter {
968 972
  public:
969 973

	
970 974
    typedef _Graph Graph;
971 975
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
972 976

	
973 977
  private:
974 978

	
975 979

	
976 980
    std::ostream* _os;
977 981
    bool local_os;
978 982

	
979 983
    const Graph& _graph;
980 984

	
981 985
    std::string _nodes_caption;
982 986
    std::string _edges_caption;
983 987
    std::string _attributes_caption;
984 988

	
985 989
    typedef std::map<Node, std::string> NodeIndex;
986 990
    NodeIndex _node_index;
987 991
    typedef std::map<Edge, std::string> EdgeIndex;
988 992
    EdgeIndex _edge_index;
989 993

	
990 994
    typedef std::vector<std::pair<std::string,
991 995
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
992 996
    NodeMaps _node_maps;
993 997

	
994 998
    typedef std::vector<std::pair<std::string,
995 999
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
996 1000
    EdgeMaps _edge_maps;
997 1001

	
998 1002
    typedef std::vector<std::pair<std::string,
999 1003
      _writer_bits::ValueStorageBase*> > Attributes;
1000 1004
    Attributes _attributes;
1001 1005

	
1002 1006
    bool _skip_nodes;
1003 1007
    bool _skip_edges;
1004 1008

	
1005 1009
  public:
1006 1010

	
1007 1011
    /// \brief Constructor
1008 1012
    ///
1009 1013
    /// Construct a directed graph writer, which writes to the given
1010 1014
    /// output stream.
1011 1015
    GraphWriter(std::ostream& is, const Graph& graph)
1012 1016
      : _os(&is), local_os(false), _graph(graph),
1013 1017
        _skip_nodes(false), _skip_edges(false) {}
1014 1018

	
1015 1019
    /// \brief Constructor
1016 1020
    ///
1017 1021
    /// Construct a directed graph writer, which writes to the given
1018 1022
    /// output file.
1019 1023
    GraphWriter(const std::string& fn, const Graph& graph)
1020 1024
      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
1021
        _skip_nodes(false), _skip_edges(false) {}
1025
        _skip_nodes(false), _skip_edges(false) {
1026
      if (!(*_os)) throw IoError(fn, "Cannot write file");
1027
    }
1022 1028

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

	
1031 1039
    /// \brief Destructor
1032 1040
    ~GraphWriter() {
1033 1041
      for (typename NodeMaps::iterator it = _node_maps.begin();
1034 1042
           it != _node_maps.end(); ++it) {
1035 1043
        delete it->second;
1036 1044
      }
1037 1045

	
1038 1046
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1039 1047
           it != _edge_maps.end(); ++it) {
1040 1048
        delete it->second;
1041 1049
      }
1042 1050

	
1043 1051
      for (typename Attributes::iterator it = _attributes.begin();
1044 1052
           it != _attributes.end(); ++it) {
1045 1053
        delete it->second;
1046 1054
      }
1047 1055

	
1048 1056
      if (local_os) {
1049 1057
        delete _os;
1050 1058
      }
1051 1059
    }
1052 1060

	
1053 1061
  private:
1054 1062

	
1055 1063
    friend GraphWriter<Graph> graphWriter<>(std::ostream& os,
1056 1064
                                            const Graph& graph);
1057 1065
    friend GraphWriter<Graph> graphWriter<>(const std::string& fn,
1058 1066
                                            const Graph& graph);
1059 1067
    friend GraphWriter<Graph> graphWriter<>(const char *fn,
1060 1068
                                            const Graph& graph);
1061 1069

	
1062 1070
    GraphWriter(GraphWriter& other)
1063 1071
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
1064 1072
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1065 1073

	
1066 1074
      other._os = 0;
1067 1075
      other.local_os = false;
1068 1076

	
1069 1077
      _node_index.swap(other._node_index);
1070 1078
      _edge_index.swap(other._edge_index);
1071 1079

	
1072 1080
      _node_maps.swap(other._node_maps);
1073 1081
      _edge_maps.swap(other._edge_maps);
1074 1082
      _attributes.swap(other._attributes);
1075 1083

	
1076 1084
      _nodes_caption = other._nodes_caption;
1077 1085
      _edges_caption = other._edges_caption;
1078 1086
      _attributes_caption = other._attributes_caption;
1079 1087
    }
1080 1088

	
1081 1089
    GraphWriter& operator=(const GraphWriter&);
1082 1090

	
1083 1091
  public:
1084 1092

	
1085 1093
    /// \name Writing rules
1086 1094
    /// @{
1087 1095

	
1088 1096
    /// \brief Node map writing rule
1089 1097
    ///
1090 1098
    /// Add a node map writing rule to the writer.
1091 1099
    template <typename Map>
1092 1100
    GraphWriter& nodeMap(const std::string& caption, const Map& map) {
1093 1101
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1094 1102
      _writer_bits::MapStorageBase<Node>* storage =
1095 1103
        new _writer_bits::MapStorage<Node, Map>(map);
1096 1104
      _node_maps.push_back(std::make_pair(caption, storage));
1097 1105
      return *this;
1098 1106
    }
1099 1107

	
1100 1108
    /// \brief Node map writing rule
1101 1109
    ///
1102 1110
    /// Add a node map writing rule with specialized converter to the
1103 1111
    /// writer.
1104 1112
    template <typename Map, typename Converter>
1105 1113
    GraphWriter& nodeMap(const std::string& caption, const Map& map,
1106 1114
                           const Converter& converter = Converter()) {
1107 1115
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1108 1116
      _writer_bits::MapStorageBase<Node>* storage =
1109 1117
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1110 1118
      _node_maps.push_back(std::make_pair(caption, storage));
1111 1119
      return *this;
1112 1120
    }
1113 1121

	
1114 1122
    /// \brief Edge map writing rule
1115 1123
    ///
1116 1124
    /// Add an edge map writing rule to the writer.
1117 1125
    template <typename Map>
1118 1126
    GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1119 1127
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1120 1128
      _writer_bits::MapStorageBase<Edge>* storage =
1121 1129
        new _writer_bits::MapStorage<Edge, Map>(map);
1122 1130
      _edge_maps.push_back(std::make_pair(caption, storage));
1123 1131
      return *this;
1124 1132
    }
1125 1133

	
1126 1134
    /// \brief Edge map writing rule
1127 1135
    ///
1128 1136
    /// Add an edge map writing rule with specialized converter to the
1129 1137
    /// writer.
1130 1138
    template <typename Map, typename Converter>
1131 1139
    GraphWriter& edgeMap(const std::string& caption, const Map& map,
1132 1140
                          const Converter& converter = Converter()) {
1133 1141
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1134 1142
      _writer_bits::MapStorageBase<Edge>* storage =
1135 1143
        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1136 1144
      _edge_maps.push_back(std::make_pair(caption, storage));
1137 1145
      return *this;
1138 1146
    }
1139 1147

	
1140 1148
    /// \brief Arc map writing rule
1141 1149
    ///
1142 1150
    /// Add an arc map writing rule to the writer.
1143 1151
    template <typename Map>
1144 1152
    GraphWriter& arcMap(const std::string& caption, const Map& map) {
1145 1153
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1146 1154
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1147 1155
        new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1148 1156
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1149 1157
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1150 1158
        new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1151 1159
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1152 1160
      return *this;
1153 1161
    }
1154 1162

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

	
1174 1182
    /// \brief Attribute writing rule
1175 1183
    ///
1176 1184
    /// Add an attribute writing rule to the writer.
1177 1185
    template <typename Value>
1178 1186
    GraphWriter& attribute(const std::string& caption, const Value& value) {
1179 1187
      _writer_bits::ValueStorageBase* storage =
1180 1188
        new _writer_bits::ValueStorage<Value>(value);
1181 1189
      _attributes.push_back(std::make_pair(caption, storage));
1182 1190
      return *this;
1183 1191
    }
1184 1192

	
1185 1193
    /// \brief Attribute writing rule
1186 1194
    ///
1187 1195
    /// Add an attribute writing rule with specialized converter to the
1188 1196
    /// writer.
1189 1197
    template <typename Value, typename Converter>
1190 1198
    GraphWriter& attribute(const std::string& caption, const Value& value,
1191 1199
                             const Converter& converter = Converter()) {
1192 1200
      _writer_bits::ValueStorageBase* storage =
1193 1201
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1194 1202
      _attributes.push_back(std::make_pair(caption, storage));
1195 1203
      return *this;
1196 1204
    }
1197 1205

	
1198 1206
    /// \brief Node writing rule
1199 1207
    ///
1200 1208
    /// Add a node writing rule to the writer.
1201 1209
    GraphWriter& node(const std::string& caption, const Node& node) {
1202 1210
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
1203 1211
      Converter converter(_node_index);
1204 1212
      _writer_bits::ValueStorageBase* storage =
1205 1213
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1206 1214
      _attributes.push_back(std::make_pair(caption, storage));
1207 1215
      return *this;
1208 1216
    }
1209 1217

	
1210 1218
    /// \brief Edge writing rule
1211 1219
    ///
1212 1220
    /// Add an edge writing rule to writer.
1213 1221
    GraphWriter& edge(const std::string& caption, const Edge& edge) {
1214 1222
      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1215 1223
      Converter converter(_edge_index);
1216 1224
      _writer_bits::ValueStorageBase* storage =
1217 1225
        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1218 1226
      _attributes.push_back(std::make_pair(caption, storage));
1219 1227
      return *this;
1220 1228
    }
1221 1229

	
... ...
@@ -1387,356 +1395,360 @@
1387 1395
      if (label == 0) {
1388 1396
        *_os << "label" << '\t';
1389 1397
      }
1390 1398
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1391 1399
           it != _edge_maps.end(); ++it) {
1392 1400
        _writer_bits::writeToken(*_os, it->first) << '\t';
1393 1401
      }
1394 1402
      *_os << std::endl;
1395 1403

	
1396 1404
      std::vector<Edge> edges;
1397 1405
      for (EdgeIt n(_graph); n != INVALID; ++n) {
1398 1406
        edges.push_back(n);
1399 1407
      }
1400 1408

	
1401 1409
      if (label == 0) {
1402 1410
        IdMap<Graph, Edge> id_map(_graph);
1403 1411
        _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1404 1412
        std::sort(edges.begin(), edges.end(), id_less);
1405 1413
      } else {
1406 1414
        label->sort(edges);
1407 1415
      }
1408 1416

	
1409 1417
      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1410 1418
        Edge e = edges[i];
1411 1419
        _writer_bits::writeToken(*_os, _node_index.
1412 1420
                                 find(_graph.u(e))->second);
1413 1421
        *_os << '\t';
1414 1422
        _writer_bits::writeToken(*_os, _node_index.
1415 1423
                                 find(_graph.v(e))->second);
1416 1424
        *_os << '\t';
1417 1425
        if (label == 0) {
1418 1426
          std::ostringstream os;
1419 1427
          os << _graph.id(e);
1420 1428
          _writer_bits::writeToken(*_os, os.str());
1421 1429
          *_os << '\t';
1422 1430
          _edge_index.insert(std::make_pair(e, os.str()));
1423 1431
        }
1424 1432
        for (typename EdgeMaps::iterator it = _edge_maps.begin();
1425 1433
             it != _edge_maps.end(); ++it) {
1426 1434
          std::string value = it->second->get(e);
1427 1435
          _writer_bits::writeToken(*_os, value);
1428 1436
          if (it->first == "label") {
1429 1437
            _edge_index.insert(std::make_pair(e, value));
1430 1438
          }
1431 1439
          *_os << '\t';
1432 1440
        }
1433 1441
        *_os << std::endl;
1434 1442
      }
1435 1443
    }
1436 1444

	
1437 1445
    void createEdgeIndex() {
1438 1446
      _writer_bits::MapStorageBase<Edge>* label = 0;
1439 1447
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1440 1448
           it != _edge_maps.end(); ++it) {
1441 1449
        if (it->first == "label") {
1442 1450
          label = it->second;
1443 1451
          break;
1444 1452
        }
1445 1453
      }
1446 1454

	
1447 1455
      if (label == 0) {
1448 1456
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1449 1457
          std::ostringstream os;
1450 1458
          os << _graph.id(e);
1451 1459
          _edge_index.insert(std::make_pair(e, os.str()));
1452 1460
        }
1453 1461
      } else {
1454 1462
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1455 1463
          std::string value = label->get(e);
1456 1464
          _edge_index.insert(std::make_pair(e, value));
1457 1465
        }
1458 1466
      }
1459 1467
    }
1460 1468

	
1461 1469
    void writeAttributes() {
1462 1470
      if (_attributes.empty()) return;
1463 1471
      *_os << "@attributes";
1464 1472
      if (!_attributes_caption.empty()) {
1465 1473
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1466 1474
      }
1467 1475
      *_os << std::endl;
1468 1476
      for (typename Attributes::iterator it = _attributes.begin();
1469 1477
           it != _attributes.end(); ++it) {
1470 1478
        _writer_bits::writeToken(*_os, it->first) << ' ';
1471 1479
        _writer_bits::writeToken(*_os, it->second->get());
1472 1480
        *_os << std::endl;
1473 1481
      }
1474 1482
    }
1475 1483

	
1476 1484
  public:
1477 1485

	
1478 1486
    /// \name Execution of the writer
1479 1487
    /// @{
1480 1488

	
1481 1489
    /// \brief Start the batch processing
1482 1490
    ///
1483 1491
    /// This function starts the batch processing.
1484 1492
    void run() {
1485 1493
      if (!_skip_nodes) {
1486 1494
        writeNodes();
1487 1495
      } else {
1488 1496
        createNodeIndex();
1489 1497
      }
1490 1498
      if (!_skip_edges) {
1491 1499
        writeEdges();
1492 1500
      } else {
1493 1501
        createEdgeIndex();
1494 1502
      }
1495 1503
      writeAttributes();
1496 1504
    }
1497 1505

	
1498 1506
    /// \brief Give back the stream of the writer
1499 1507
    ///
1500 1508
    /// Give back the stream of the writer
1501 1509
    std::ostream& ostream() {
1502 1510
      return *_os;
1503 1511
    }
1504 1512

	
1505 1513
    /// @}
1506 1514
  };
1507 1515

	
1508 1516
  /// \brief Return a \ref GraphWriter class
1509 1517
  ///
1510 1518
  /// This function just returns a \ref GraphWriter class.
1511 1519
  /// \relates GraphWriter
1512 1520
  template <typename Graph>
1513 1521
  GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph) {
1514 1522
    GraphWriter<Graph> tmp(os, graph);
1515 1523
    return tmp;
1516 1524
  }
1517 1525

	
1518 1526
  /// \brief Return a \ref GraphWriter class
1519 1527
  ///
1520 1528
  /// This function just returns a \ref GraphWriter class.
1521 1529
  /// \relates GraphWriter
1522 1530
  template <typename Graph>
1523 1531
  GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph) {
1524 1532
    GraphWriter<Graph> tmp(fn, graph);
1525 1533
    return tmp;
1526 1534
  }
1527 1535

	
1528 1536
  /// \brief Return a \ref GraphWriter class
1529 1537
  ///
1530 1538
  /// This function just returns a \ref GraphWriter class.
1531 1539
  /// \relates GraphWriter
1532 1540
  template <typename Graph>
1533 1541
  GraphWriter<Graph> graphWriter(const char* fn, const Graph& graph) {
1534 1542
    GraphWriter<Graph> tmp(fn, graph);
1535 1543
    return tmp;
1536 1544
  }
1537 1545

	
1538 1546
  class SectionWriter;
1539 1547

	
1540 1548
  SectionWriter sectionWriter(std::istream& is);
1541 1549
  SectionWriter sectionWriter(const std::string& fn);
1542 1550
  SectionWriter sectionWriter(const char* fn);
1543 1551

	
1544 1552
  /// \ingroup lemon_io
1545 1553
  ///
1546 1554
  /// \brief Section writer class
1547 1555
  ///
1548 1556
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
1549 1557
  /// which contain any data in arbitrary format. Such sections can be
1550 1558
  /// written with this class. A writing rule can be added to the
1551 1559
  /// class with two different functions. With the \c sectionLines()
1552 1560
  /// function a generator can write the section line-by-line, while
1553 1561
  /// with the \c sectionStream() member the section can be written to
1554 1562
  /// an output stream.
1555 1563
  class SectionWriter {
1556 1564
  private:
1557 1565

	
1558 1566
    std::ostream* _os;
1559 1567
    bool local_os;
1560 1568

	
1561 1569
    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
1562 1570
    Sections;
1563 1571

	
1564 1572
    Sections _sections;
1565 1573

	
1566 1574
  public:
1567 1575

	
1568 1576
    /// \brief Constructor
1569 1577
    ///
1570 1578
    /// Construct a section writer, which writes to the given output
1571 1579
    /// stream.
1572 1580
    SectionWriter(std::ostream& os)
1573 1581
      : _os(&os), local_os(false) {}
1574 1582

	
1575 1583
    /// \brief Constructor
1576 1584
    ///
1577 1585
    /// Construct a section writer, which writes into the given file.
1578 1586
    SectionWriter(const std::string& fn)
1579
      : _os(new std::ofstream(fn.c_str())), local_os(true) {}
1587
      : _os(new std::ofstream(fn.c_str())), local_os(true) {
1588
      if (!(*_os)) throw IoError(fn, "Cannot write file");
1589
    }
1580 1590

	
1581 1591
    /// \brief Constructor
1582 1592
    ///
1583 1593
    /// Construct a section writer, which writes into the given file.
1584 1594
    SectionWriter(const char* fn)
1585
      : _os(new std::ofstream(fn)), local_os(true) {}
1595
      : _os(new std::ofstream(fn)), local_os(true) {
1596
      if (!(*_os)) throw IoError(fn, "Cannot write file");
1597
    }
1586 1598

	
1587 1599
    /// \brief Destructor
1588 1600
    ~SectionWriter() {
1589 1601
      for (Sections::iterator it = _sections.begin();
1590 1602
           it != _sections.end(); ++it) {
1591 1603
        delete it->second;
1592 1604
      }
1593 1605

	
1594 1606
      if (local_os) {
1595 1607
        delete _os;
1596 1608
      }
1597 1609

	
1598 1610
    }
1599 1611

	
1600 1612
  private:
1601 1613

	
1602 1614
    friend SectionWriter sectionWriter(std::ostream& os);
1603 1615
    friend SectionWriter sectionWriter(const std::string& fn);
1604 1616
    friend SectionWriter sectionWriter(const char* fn);
1605 1617

	
1606 1618
    SectionWriter(SectionWriter& other)
1607 1619
      : _os(other._os), local_os(other.local_os) {
1608 1620

	
1609 1621
      other._os = 0;
1610 1622
      other.local_os = false;
1611 1623

	
1612 1624
      _sections.swap(other._sections);
1613 1625
    }
1614 1626

	
1615 1627
    SectionWriter& operator=(const SectionWriter&);
1616 1628

	
1617 1629
  public:
1618 1630

	
1619 1631
    /// \name Section writers
1620 1632
    /// @{
1621 1633

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

	
1666 1678

	
1667 1679
    /// \brief Add a section writer with stream oriented writing
1668 1680
    ///
1669 1681
    /// The first parameter is the type of the section, the second is
1670 1682
    /// a functor, which takes a \c std::ostream& parameter. The
1671 1683
    /// functor writes the section to the output stream.
1672 1684
    /// \warning The last line must be closed with end-line character.
1673 1685
    template <typename Functor>
1674 1686
    SectionWriter& sectionStream(const std::string& type, Functor functor) {
1675 1687
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1676 1688
      _sections.push_back(std::make_pair(type,
1677 1689
         new _writer_bits::StreamSection<Functor>(functor)));
1678 1690
      return *this;
1679 1691
    }
1680 1692

	
1681 1693
    /// @}
1682 1694

	
1683 1695
  public:
1684 1696

	
1685 1697

	
1686 1698
    /// \name Execution of the writer
1687 1699
    /// @{
1688 1700

	
1689 1701
    /// \brief Start the batch processing
1690 1702
    ///
1691 1703
    /// This function starts the batch processing.
1692 1704
    void run() {
1693 1705

	
1694 1706
      LEMON_ASSERT(_os != 0, "This writer is assigned to an other writer");
1695 1707

	
1696 1708
      for (Sections::iterator it = _sections.begin();
1697 1709
           it != _sections.end(); ++it) {
1698 1710
        (*_os) << '@' << it->first << std::endl;
1699 1711
        it->second->process(*_os);
1700 1712
      }
1701 1713
    }
1702 1714

	
1703 1715
    /// \brief Give back the stream of the writer
1704 1716
    ///
1705 1717
    /// Returns the stream of the writer
1706 1718
    std::ostream& ostream() {
1707 1719
      return *_os;
1708 1720
    }
1709 1721

	
1710 1722
    /// @}
1711 1723

	
1712 1724
  };
1713 1725

	
1714 1726
  /// \brief Return a \ref SectionWriter class
1715 1727
  ///
1716 1728
  /// This function just returns a \ref SectionWriter class.
1717 1729
  /// \relates SectionWriter
1718 1730
  inline SectionWriter sectionWriter(std::ostream& os) {
1719 1731
    SectionWriter tmp(os);
1720 1732
    return tmp;
1721 1733
  }
1722 1734

	
1723 1735
  /// \brief Return a \ref SectionWriter class
1724 1736
  ///
1725 1737
  /// This function just returns a \ref SectionWriter class.
1726 1738
  /// \relates SectionWriter
1727 1739
  inline SectionWriter sectionWriter(const std::string& fn) {
1728 1740
    SectionWriter tmp(fn);
1729 1741
    return tmp;
1730 1742
  }
1731 1743

	
1732 1744
  /// \brief Return a \ref SectionWriter class
1733 1745
  ///
1734 1746
  /// This function just returns a \ref SectionWriter class.
1735 1747
  /// \relates SectionWriter
1736 1748
  inline SectionWriter sectionWriter(const char* fn) {
1737 1749
    SectionWriter tmp(fn);
1738 1750
    return tmp;
1739 1751
  }
1740 1752
}
1741 1753

	
1742 1754
#endif
0 comments (0 inline)