gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 11 0
merge default
3 files changed with 389 insertions and 523 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -4,67 +4,67 @@
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(g, "digraph.lgf"). // 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(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
... ...
@@ -265,98 +265,99 @@
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);
Ignore white space 6 line context
... ...
@@ -63,97 +63,97 @@
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)))
Ignore white space 6 line context
... ...
@@ -90,265 +90,260 @@
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) {
... ...
@@ -995,97 +990,96 @@
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; };
... ...
@@ -1278,163 +1272,152 @@
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 = BfsVisitDefaultTraits<_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

	
Ignore white space 6 line context
... ...
@@ -84,97 +84,96 @@
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;
Ignore white space 6 line context
... ...
@@ -91,247 +91,241 @@
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()
... ...
@@ -929,97 +923,96 @@
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; };
... ...
@@ -1225,163 +1218,152 @@
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 = DfsVisitDefaultTraits<_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

	
Ignore white space 6 line context
... ...
@@ -180,106 +180,96 @@
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;
... ...
@@ -287,177 +277,182 @@
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
... ...
@@ -1113,119 +1108,117 @@
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)
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_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
172
    Exception() {}
173
    ///\e
44
    ///Constructor
45
    Exception() throw() {}
46
    ///Virtual destructor
174 47
    virtual ~Exception() throw() {}
175
    ///\e
48
    ///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) throw() : Exception() {
68
      message(error._message);
69
      file(error._file);
70
    }
71

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

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

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

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

	
96
    /// Virtual destructor
97
    virtual ~IoError() throw() {}
98

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

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

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

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

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

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

	
193 152
  };
194 153

	
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 {
154
  /// \brief Format error
155
  ///
156
  /// This exception is thrown when an input file has wrong
157
  /// format or a data representation is not legal.
158
  class FormatError : public Exception {
237 159
  protected:
238
    ExceptionMember<std::string> _message;
239
    ExceptionMember<std::string> _file;
160
    std::string _message;
161
    std::string _file;
240 162
    int _line;
241 163

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

	
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
      }
167
    /// Copy constructor
168
    FormatError(const FormatError &error) throw() : Exception() {
169
      message(error._message);
170
      file(error._file);
171
      line(error._line);
274 172
    }
275 173

	
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
      }
174
    /// Constructor
175
    explicit FormatError(const char *message) throw() {
176
      FormatError::message(message);
177
      _line = 0;
285 178
    }
286 179

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

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

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

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

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

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

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

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

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

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

	
239
    /// \brief Returns the filename
240
    ///
241
    /// Returns the filename or an empty string if it was not specified.
242
    const std::string& file() const throw() {
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;
... ...
@@ -1121,71 +1122,81 @@
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("Cannot write file", file_name);
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("Cannot write file", file_name);
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
... ...
@@ -3,101 +3,103 @@
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,
... ...
@@ -121,231 +123,231 @@
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;
... ...
@@ -416,157 +418,164 @@
416 418
  /// converted to the value type of the map. If the functor is not set,
417 419
  /// then a default conversion will be used. One map can be read into
418 420
  /// multiple map objects at the same time. The \c attribute(), \c
419 421
  /// node() and \c arc() functions are used to add attribute reading
420 422
  /// rules.
421 423
  ///
422 424
  ///\code
423 425
  /// DigraphReader<Digraph>(digraph, std::cin).
424 426
  ///   nodeMap("coordinates", coord_map).
425 427
  ///   arcMap("capacity", cap_map).
426 428
  ///   node("source", src).
427 429
  ///   node("target", trg).
428 430
  ///   attribute("caption", caption).
429 431
  ///   run();
430 432
  ///\endcode
431 433
  ///
432 434
  /// By default the reader uses the first section in the file of the
433 435
  /// proper type. If a section has an optional name, then it can be
434 436
  /// selected for reading by giving an optional name parameter to the
435 437
  /// \c nodes(), \c arcs() or \c attributes() functions.
436 438
  ///
437 439
  /// The \c useNodes() and \c useArcs() functions are used to tell the reader
438 440
  /// that the nodes or arcs should not be constructed (added to the
439 441
  /// graph) during the reading, but instead the label map of the items
440 442
  /// are given as a parameter of these functions. An
441 443
  /// application of these functions is multipass reading, which is
442 444
  /// important if two \c \@arcs sections must be read from the
443 445
  /// file. In this case the first phase would read the node set and one
444 446
  /// of the arc sets, while the second phase would read the second arc
445 447
  /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
446 448
  /// The previously read label node map should be passed to the \c
447 449
  /// useNodes() functions. Another application of multipass reading when
448 450
  /// paths are given as a node map or an arc map.
449 451
  /// It is impossible to read this in
450 452
  /// a single pass, because the arcs are not constructed when the node
451 453
  /// maps are read.
452 454
  template <typename _Digraph>
453 455
  class DigraphReader {
454 456
  public:
455 457

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

	
459 461
  private:
460 462

	
461 463

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

	
465 468
    Digraph& _digraph;
466 469

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

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

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

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

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

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

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

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

	
497 500
  public:
498 501

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

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

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

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

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

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

	
543 552
      if (local_is) {
544 553
        delete _is;
545 554
      }
546 555

	
547 556
    }
548 557

	
549 558
  private:
550 559

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

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

	
563 572
      other._is = 0;
564 573
      other.local_is = false;
565 574

	
566 575
      _node_index.swap(other._node_index);
567 576
      _arc_index.swap(other._arc_index);
568 577

	
569 578
      _node_maps.swap(other._node_maps);
570 579
      _arc_maps.swap(other._arc_maps);
571 580
      _attributes.swap(other._attributes);
572 581

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

	
811 820
    /// @}
812 821

	
813 822
  private:
814 823

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

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

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

	
840 849
    void readNodes() {
841 850

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

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

	
854 863
      {
855 864
        std::map<std::string, int> maps;
856 865

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

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

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

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

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

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

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

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

	
933 942
    void readArcs() {
934 943

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

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

	
947 956
      {
948 957
        std::map<std::string, int> maps;
949 958

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

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

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

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

	
987 996
        std::string source_token;
988 997
        std::string target_token;
989 998

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

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

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

	
1007 1016
        Arc a;
1008 1017
        if (!_use_arcs) {
1009 1018

	
1010 1019
          typename NodeIndex::iterator it;
1011 1020

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

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

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

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

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

	
1054 1063
    void readAttributes() {
1055 1064

	
1056 1065
      std::set<std::string> read_attr;
1057 1066

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

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

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

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

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

	
1102 1111
  public:
1103 1112

	
1104 1113
    /// \name Execution of the reader
1105 1114
    /// @{
1106 1115

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

	
1116 1122
      bool nodes_done = _skip_nodes;
1117 1123
      bool arcs_done = _skip_arcs;
1118 1124
      bool attributes_done = false;
1119 1125

	
1120 1126
      line_num = 0;
1121 1127
      readLine();
1122 1128
      skipSection();
1123 1129

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

	
1132 1138
          if (line >> c)
1133
            throw DataFormatError("Extra character on the end of line");
1139
            throw FormatError("Extra character at the end of line");
1134 1140

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

	
1161 1168
      if (!nodes_done) {
1162
        throw DataFormatError("Section @nodes not found");
1169
        throw FormatError("Section @nodes not found");
1163 1170
      }
1164 1171

	
1165 1172
      if (!arcs_done) {
1166
        throw DataFormatError("Section @arcs not found");
1173
        throw FormatError("Section @arcs not found");
1167 1174
      }
1168 1175

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

	
1173 1180
    }
1174 1181

	
1175 1182
    /// @}
1176 1183

	
1177 1184
  };
1178 1185

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

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

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

	
1211 1218
  template <typename Graph>
1212 1219
  class GraphReader;
1213 1220

	
1214 1221
  template <typename Graph>
1215 1222
  GraphReader<Graph> graphReader(Graph& graph,
1216 1223
                                 std::istream& is = std::cin);
1217 1224

	
1218 1225
  template <typename Graph>
1219 1226
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
1220 1227

	
1221 1228
  template <typename Graph>
1222 1229
  GraphReader<Graph> graphReader(Graph& graph, const char *fn);
1223 1230

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

	
1243 1250
    typedef _Graph Graph;
1244 1251
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1245 1252

	
1246 1253
  private:
1247 1254

	
1248 1255
    std::istream* _is;
1249 1256
    bool local_is;
1257
    std::string _filename;
1250 1258

	
1251 1259
    Graph& _graph;
1252 1260

	
1253 1261
    std::string _nodes_caption;
1254 1262
    std::string _edges_caption;
1255 1263
    std::string _attributes_caption;
1256 1264

	
1257 1265
    typedef std::map<std::string, Node> NodeIndex;
1258 1266
    NodeIndex _node_index;
1259 1267
    typedef std::map<std::string, Edge> EdgeIndex;
1260 1268
    EdgeIndex _edge_index;
1261 1269

	
1262 1270
    typedef std::vector<std::pair<std::string,
1263 1271
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1264 1272
    NodeMaps _node_maps;
1265 1273

	
1266 1274
    typedef std::vector<std::pair<std::string,
1267 1275
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1268 1276
    EdgeMaps _edge_maps;
1269 1277

	
1270 1278
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1271 1279
      Attributes;
1272 1280
    Attributes _attributes;
1273 1281

	
1274 1282
    bool _use_nodes;
1275 1283
    bool _use_edges;
1276 1284

	
1277 1285
    bool _skip_nodes;
1278 1286
    bool _skip_edges;
1279 1287

	
1280 1288
    int line_num;
1281 1289
    std::istringstream line;
1282 1290

	
1283 1291
  public:
1284 1292

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

	
1294 1302
    /// \brief Constructor
1295 1303
    ///
1296 1304
    /// Construct an undirected graph reader, which reads from the given
1297 1305
    /// file.
1298 1306
    GraphReader(Graph& graph, const std::string& fn)
1299
      : _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),
1300 1309
        _use_nodes(false), _use_edges(false),
1301
        _skip_nodes(false), _skip_edges(false) {}
1310
        _skip_nodes(false), _skip_edges(false) {
1311
      if (!(*_is)) throw IoError("Cannot open file", fn);
1312
    }
1302 1313

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

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

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

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

	
1329 1343
      if (local_is) {
1330 1344
        delete _is;
1331 1345
      }
1332 1346

	
1333 1347
    }
1334 1348

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

	
1341 1355
    GraphReader(GraphReader& other)
1342 1356
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1343 1357
        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
1344 1358
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1345 1359

	
1346 1360
      other._is = 0;
1347 1361
      other.local_is = false;
1348 1362

	
1349 1363
      _node_index.swap(other._node_index);
1350 1364
      _edge_index.swap(other._edge_index);
1351 1365

	
1352 1366
      _node_maps.swap(other._node_maps);
1353 1367
      _edge_maps.swap(other._edge_maps);
1354 1368
      _attributes.swap(other._attributes);
1355 1369

	
1356 1370
      _nodes_caption = other._nodes_caption;
1357 1371
      _edges_caption = other._edges_caption;
1358 1372
      _attributes_caption = other._attributes_caption;
... ...
@@ -1631,503 +1645,511 @@
1631 1645
    ///
1632 1646
    /// Omit the reading of the edge section. This implies that each edge
1633 1647
    /// map reading rule will be abandoned, and the edges of the graph
1634 1648
    /// will not be constructed.
1635 1649
    GraphReader& skipEdges() {
1636 1650
      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
1637 1651
      _skip_edges = true;
1638 1652
      return *this;
1639 1653
    }
1640 1654

	
1641 1655
    /// @}
1642 1656

	
1643 1657
  private:
1644 1658

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

	
1658 1672
    bool readSuccess() {
1659 1673
      return static_cast<bool>(*_is);
1660 1674
    }
1661 1675

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

	
1670 1684
    void readNodes() {
1671 1685

	
1672 1686
      std::vector<int> map_index(_node_maps.size());
1673 1687
      int map_num, label_index;
1674 1688

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

	
1684 1698
      {
1685 1699
        std::map<std::string, int> maps;
1686 1700

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

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

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

	
1721 1735
      while (readLine() && line >> c && c != '@') {
1722 1736
        line.putback(c);
1723 1737

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

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

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

	
1757 1771
      }
1758 1772
      if (readSuccess()) {
1759 1773
        line.putback(c);
1760 1774
      }
1761 1775
    }
1762 1776

	
1763 1777
    void readEdges() {
1764 1778

	
1765 1779
      std::vector<int> map_index(_edge_maps.size());
1766 1780
      int map_num, label_index;
1767 1781

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

	
1777 1791
      {
1778 1792
        std::map<std::string, int> maps;
1779 1793

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

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

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

	
1814 1828
      while (readLine() && line >> c && c != '@') {
1815 1829
        line.putback(c);
1816 1830

	
1817 1831
        std::string source_token;
1818 1832
        std::string target_token;
1819 1833

	
1820 1834
        if (!_reader_bits::readToken(line, source_token))
1821
          throw DataFormatError("Node u not found");
1835
          throw FormatError("Node u not found");
1822 1836

	
1823 1837
        if (!_reader_bits::readToken(line, target_token))
1824
          throw DataFormatError("Node v not found");
1838
          throw FormatError("Node v not found");
1825 1839

	
1826 1840
        std::vector<std::string> tokens(map_num);
1827 1841
        for (int i = 0; i < map_num; ++i) {
1828 1842
          if (!_reader_bits::readToken(line, tokens[i])) {
1829 1843
            std::ostringstream msg;
1830 1844
            msg << "Column not found (" << i + 1 << ")";
1831
            throw DataFormatError(msg.str().c_str());
1845
            throw FormatError(msg.str());
1832 1846
          }
1833 1847
        }
1834 1848
        if (line >> std::ws >> c)
1835
          throw DataFormatError("Extra character on the end of line");
1849
          throw FormatError("Extra character at the end of line");
1836 1850

	
1837 1851
        Edge e;
1838 1852
        if (!_use_edges) {
1839 1853

	
1840 1854
          typename NodeIndex::iterator it;
1841 1855

	
1842 1856
          it = _node_index.find(source_token);
1843 1857
          if (it == _node_index.end()) {
1844 1858
            std::ostringstream msg;
1845 1859
            msg << "Item not found: " << source_token;
1846
            throw DataFormatError(msg.str().c_str());
1860
            throw FormatError(msg.str());
1847 1861
          }
1848 1862
          Node source = it->second;
1849 1863

	
1850 1864
          it = _node_index.find(target_token);
1851 1865
          if (it == _node_index.end()) {
1852 1866
            std::ostringstream msg;
1853 1867
            msg << "Item not found: " << target_token;
1854
            throw DataFormatError(msg.str().c_str());
1868
            throw FormatError(msg.str());
1855 1869
          }
1856 1870
          Node target = it->second;
1857 1871

	
1858 1872
          e = _graph.addEdge(source, target);
1859 1873
          if (label_index != -1)
1860 1874
            _edge_index.insert(std::make_pair(tokens[label_index], e));
1861 1875
        } else {
1862 1876
          if (label_index == -1)
1863
            throw DataFormatError("Label map not found in file");
1877
            throw FormatError("Label map not found");
1864 1878
          typename std::map<std::string, Edge>::iterator it =
1865 1879
            _edge_index.find(tokens[label_index]);
1866 1880
          if (it == _edge_index.end()) {
1867 1881
            std::ostringstream msg;
1868 1882
            msg << "Edge with label not found: " << tokens[label_index];
1869
            throw DataFormatError(msg.str().c_str());
1883
            throw FormatError(msg.str());
1870 1884
          }
1871 1885
          e = it->second;
1872 1886
        }
1873 1887

	
1874 1888
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1875 1889
          _edge_maps[i].second->set(e, tokens[map_index[i]]);
1876 1890
        }
1877 1891

	
1878 1892
      }
1879 1893
      if (readSuccess()) {
1880 1894
        line.putback(c);
1881 1895
      }
1882 1896
    }
1883 1897

	
1884 1898
    void readAttributes() {
1885 1899

	
1886 1900
      std::set<std::string> read_attr;
1887 1901

	
1888 1902
      char c;
1889 1903
      while (readLine() && line >> c && c != '@') {
1890 1904
        line.putback(c);
1891 1905

	
1892 1906
        std::string attr, token;
1893 1907
        if (!_reader_bits::readToken(line, attr))
1894
          throw DataFormatError("Attribute name not found");
1908
          throw FormatError("Attribute name not found");
1895 1909
        if (!_reader_bits::readToken(line, token))
1896
          throw DataFormatError("Attribute value not found");
1910
          throw FormatError("Attribute value not found");
1897 1911
        if (line >> c)
1898
          throw DataFormatError("Extra character on the end of line");
1912
          throw FormatError("Extra character at the end of line");
1899 1913

	
1900 1914
        {
1901 1915
          std::set<std::string>::iterator it = read_attr.find(attr);
1902 1916
          if (it != read_attr.end()) {
1903 1917
            std::ostringstream msg;
1904
            msg << "Multiple occurence of attribute " << attr;
1905
            throw DataFormatError(msg.str().c_str());
1918
            msg << "Multiple occurence of attribute: " << attr;
1919
            throw FormatError(msg.str());
1906 1920
          }
1907 1921
          read_attr.insert(attr);
1908 1922
        }
1909 1923

	
1910 1924
        {
1911 1925
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1912 1926
          while (it != _attributes.end() && it->first == attr) {
1913 1927
            it->second->set(token);
1914 1928
            ++it;
1915 1929
          }
1916 1930
        }
1917 1931

	
1918 1932
      }
1919 1933
      if (readSuccess()) {
1920 1934
        line.putback(c);
1921 1935
      }
1922 1936
      for (typename Attributes::iterator it = _attributes.begin();
1923 1937
           it != _attributes.end(); ++it) {
1924 1938
        if (read_attr.find(it->first) == read_attr.end()) {
1925 1939
          std::ostringstream msg;
1926
          msg << "Attribute not found in file: " << it->first;
1927
          throw DataFormatError(msg.str().c_str());
1940
          msg << "Attribute not found: " << it->first;
1941
          throw FormatError(msg.str());
1928 1942
        }
1929 1943
      }
1930 1944
    }
1931 1945

	
1932 1946
  public:
1933 1947

	
1934 1948
    /// \name Execution of the reader
1935 1949
    /// @{
1936 1950

	
1937 1951
    /// \brief Start the batch processing
1938 1952
    ///
1939 1953
    /// This function starts the batch processing
1940 1954
    void run() {
1941 1955

	
1942 1956
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1943 1957

	
1944 1958
      bool nodes_done = _skip_nodes;
1945 1959
      bool edges_done = _skip_edges;
1946 1960
      bool attributes_done = false;
1947 1961

	
1948 1962
      line_num = 0;
1949 1963
      readLine();
1950 1964
      skipSection();
1951 1965

	
1952 1966
      while (readSuccess()) {
1953 1967
        try {
1954 1968
          char c;
1955 1969
          std::string section, caption;
1956 1970
          line >> c;
1957 1971
          _reader_bits::readToken(line, section);
1958 1972
          _reader_bits::readToken(line, caption);
1959 1973

	
1960 1974
          if (line >> c)
1961
            throw DataFormatError("Extra character on the end of line");
1975
            throw FormatError("Extra character at the end of line");
1962 1976

	
1963 1977
          if (section == "nodes" && !nodes_done) {
1964 1978
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1965 1979
              readNodes();
1966 1980
              nodes_done = true;
1967 1981
            }
1968 1982
          } else if ((section == "edges" || section == "arcs") &&
1969 1983
                     !edges_done) {
1970 1984
            if (_edges_caption.empty() || _edges_caption == caption) {
1971 1985
              readEdges();
1972 1986
              edges_done = true;
1973 1987
            }
1974 1988
          } else if (section == "attributes" && !attributes_done) {
1975 1989
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1976 1990
              readAttributes();
1977 1991
              attributes_done = true;
1978 1992
            }
1979 1993
          } else {
1980 1994
            readLine();
1981 1995
            skipSection();
1982 1996
          }
1983
        } catch (DataFormatError& error) {
1997
        } catch (FormatError& error) {
1984 1998
          error.line(line_num);
1999
          error.file(_filename);
1985 2000
          throw;
1986 2001
        }
1987 2002
      }
1988 2003

	
1989 2004
      if (!nodes_done) {
1990
        throw DataFormatError("Section @nodes not found");
2005
        throw FormatError("Section @nodes not found");
1991 2006
      }
1992 2007

	
1993 2008
      if (!edges_done) {
1994
        throw DataFormatError("Section @edges not found");
2009
        throw FormatError("Section @edges not found");
1995 2010
      }
1996 2011

	
1997 2012
      if (!attributes_done && !_attributes.empty()) {
1998
        throw DataFormatError("Section @attributes not found");
2013
        throw FormatError("Section @attributes not found");
1999 2014
      }
2000 2015

	
2001 2016
    }
2002 2017

	
2003 2018
    /// @}
2004 2019

	
2005 2020
  };
2006 2021

	
2007 2022
  /// \brief Return a \ref GraphReader class
2008 2023
  ///
2009 2024
  /// This function just returns a \ref GraphReader class.
2010 2025
  /// \relates GraphReader
2011 2026
  template <typename Graph>
2012 2027
  GraphReader<Graph> graphReader(Graph& graph, std::istream& is = std::cin) {
2013 2028
    GraphReader<Graph> tmp(graph, is);
2014 2029
    return tmp;
2015 2030
  }
2016 2031

	
2017 2032
  /// \brief Return a \ref GraphReader class
2018 2033
  ///
2019 2034
  /// This function just returns a \ref GraphReader class.
2020 2035
  /// \relates GraphReader
2021 2036
  template <typename Graph>
2022 2037
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
2023 2038
    GraphReader<Graph> tmp(graph, fn);
2024 2039
    return tmp;
2025 2040
  }
2026 2041

	
2027 2042
  /// \brief Return a \ref GraphReader class
2028 2043
  ///
2029 2044
  /// This function just returns a \ref GraphReader class.
2030 2045
  /// \relates GraphReader
2031 2046
  template <typename Graph>
2032 2047
  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
2033 2048
    GraphReader<Graph> tmp(graph, fn);
2034 2049
    return tmp;
2035 2050
  }
2036 2051

	
2037 2052
  class SectionReader;
2038 2053

	
2039 2054
  SectionReader sectionReader(std::istream& is);
2040 2055
  SectionReader sectionReader(const std::string& fn);
2041 2056
  SectionReader sectionReader(const char* fn);
2042 2057

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

	
2057 2072
    std::istream* _is;
2058 2073
    bool local_is;
2074
    std::string _filename;
2059 2075

	
2060 2076
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2061 2077
    Sections _sections;
2062 2078

	
2063 2079
    int line_num;
2064 2080
    std::istringstream line;
2065 2081

	
2066 2082
  public:
2067 2083

	
2068 2084
    /// \brief Constructor
2069 2085
    ///
2070 2086
    /// Construct a section reader, which reads from the given input
2071 2087
    /// stream.
2072 2088
    SectionReader(std::istream& is)
2073 2089
      : _is(&is), local_is(false) {}
2074 2090

	
2075 2091
    /// \brief Constructor
2076 2092
    ///
2077 2093
    /// Construct a section reader, which reads from the given file.
2078 2094
    SectionReader(const std::string& fn)
2079
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2095
      : _is(new std::ifstream(fn.c_str())), local_is(true),
2096
        _filename(fn) {
2097
      if (!(*_is)) throw IoError("Cannot open file", fn);
2098
    }
2080 2099

	
2081 2100
    /// \brief Constructor
2082 2101
    ///
2083 2102
    /// Construct a section reader, which reads from the given file.
2084 2103
    SectionReader(const char* fn)
2085
      : _is(new std::ifstream(fn)), local_is(true) {}
2104
      : _is(new std::ifstream(fn)), local_is(true),
2105
        _filename(fn) {
2106
      if (!(*_is)) throw IoError("Cannot open file", fn);
2107
    }
2086 2108

	
2087 2109
    /// \brief Destructor
2088 2110
    ~SectionReader() {
2089 2111
      for (Sections::iterator it = _sections.begin();
2090 2112
           it != _sections.end(); ++it) {
2091 2113
        delete it->second;
2092 2114
      }
2093 2115

	
2094 2116
      if (local_is) {
2095 2117
        delete _is;
2096 2118
      }
2097 2119

	
2098 2120
    }
2099 2121

	
2100 2122
  private:
2101 2123

	
2102 2124
    friend SectionReader sectionReader(std::istream& is);
2103 2125
    friend SectionReader sectionReader(const std::string& fn);
2104 2126
    friend SectionReader sectionReader(const char* fn);
2105 2127

	
2106 2128
    SectionReader(SectionReader& other)
2107 2129
      : _is(other._is), local_is(other.local_is) {
2108 2130

	
2109 2131
      other._is = 0;
2110 2132
      other.local_is = false;
2111 2133

	
2112 2134
      _sections.swap(other._sections);
2113 2135
    }
2114 2136

	
2115 2137
    SectionReader& operator=(const SectionReader&);
2116 2138

	
2117 2139
  public:
2118 2140

	
2119 2141
    /// \name Section readers
2120 2142
    /// @{
2121 2143

	
2122 2144
    /// \brief Add a section processor with line oriented reading
2123 2145
    ///
2124 2146
    /// The first parameter is the type descriptor of the section, the
2125 2147
    /// second is a functor, which takes just one \c std::string
2126 2148
    /// parameter. At the reading process, each line of the section
2127 2149
    /// will be given to the functor object. However, the empty lines
2128 2150
    /// and the comment lines are filtered out, and the leading
2129 2151
    /// whitespaces are trimmed from each processed string.
2130 2152
    ///
2131 2153
    /// For example let's see a section, which contain several
2132 2154
    /// integers, which should be inserted into a vector.
2133 2155
    ///\code
... ...
@@ -2193,121 +2215,122 @@
2193 2215
        if (line >> std::ws >> c && c != '#') {
2194 2216
          line.putback(c);
2195 2217
          return true;
2196 2218
        }
2197 2219
      }
2198 2220
      return false;
2199 2221
    }
2200 2222

	
2201 2223
    bool readSuccess() {
2202 2224
      return static_cast<bool>(*_is);
2203 2225
    }
2204 2226

	
2205 2227
    void skipSection() {
2206 2228
      char c;
2207 2229
      while (readSuccess() && line >> c && c != '@') {
2208 2230
        readLine();
2209 2231
      }
2210 2232
      line.putback(c);
2211 2233
    }
2212 2234

	
2213 2235
  public:
2214 2236

	
2215 2237

	
2216 2238
    /// \name Execution of the reader
2217 2239
    /// @{
2218 2240

	
2219 2241
    /// \brief Start the batch processing
2220 2242
    ///
2221 2243
    /// This function starts the batch processing.
2222 2244
    void run() {
2223 2245

	
2224 2246
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2225 2247

	
2226 2248
      std::set<std::string> extra_sections;
2227 2249

	
2228 2250
      line_num = 0;
2229 2251
      readLine();
2230 2252
      skipSection();
2231 2253

	
2232 2254
      while (readSuccess()) {
2233 2255
        try {
2234 2256
          char c;
2235 2257
          std::string section, caption;
2236 2258
          line >> c;
2237 2259
          _reader_bits::readToken(line, section);
2238 2260
          _reader_bits::readToken(line, caption);
2239 2261

	
2240 2262
          if (line >> c)
2241
            throw DataFormatError("Extra character on the end of line");
2263
            throw FormatError("Extra character at the end of line");
2242 2264

	
2243 2265
          if (extra_sections.find(section) != extra_sections.end()) {
2244 2266
            std::ostringstream msg;
2245
            msg << "Multiple occurence of section " << section;
2246
            throw DataFormatError(msg.str().c_str());
2267
            msg << "Multiple occurence of section: " << section;
2268
            throw FormatError(msg.str());
2247 2269
          }
2248 2270
          Sections::iterator it = _sections.find(section);
2249 2271
          if (it != _sections.end()) {
2250 2272
            extra_sections.insert(section);
2251 2273
            it->second->process(*_is, line_num);
2252 2274
          }
2253 2275
          readLine();
2254 2276
          skipSection();
2255
        } catch (DataFormatError& error) {
2277
        } catch (FormatError& error) {
2256 2278
          error.line(line_num);
2279
          error.file(_filename);
2257 2280
          throw;
2258 2281
        }
2259 2282
      }
2260 2283
      for (Sections::iterator it = _sections.begin();
2261 2284
           it != _sections.end(); ++it) {
2262 2285
        if (extra_sections.find(it->first) == extra_sections.end()) {
2263 2286
          std::ostringstream os;
2264 2287
          os << "Cannot find section: " << it->first;
2265
          throw DataFormatError(os.str().c_str());
2288
          throw FormatError(os.str());
2266 2289
        }
2267 2290
      }
2268 2291
    }
2269 2292

	
2270 2293
    /// @}
2271 2294

	
2272 2295
  };
2273 2296

	
2274 2297
  /// \brief Return a \ref SectionReader class
2275 2298
  ///
2276 2299
  /// This function just returns a \ref SectionReader class.
2277 2300
  /// \relates SectionReader
2278 2301
  inline SectionReader sectionReader(std::istream& is) {
2279 2302
    SectionReader tmp(is);
2280 2303
    return tmp;
2281 2304
  }
2282 2305

	
2283 2306
  /// \brief Return a \ref SectionReader class
2284 2307
  ///
2285 2308
  /// This function just returns a \ref SectionReader class.
2286 2309
  /// \relates SectionReader
2287 2310
  inline SectionReader sectionReader(const std::string& fn) {
2288 2311
    SectionReader tmp(fn);
2289 2312
    return tmp;
2290 2313
  }
2291 2314

	
2292 2315
  /// \brief Return a \ref SectionReader class
2293 2316
  ///
2294 2317
  /// This function just returns a \ref SectionReader class.
2295 2318
  /// \relates SectionReader
2296 2319
  inline SectionReader sectionReader(const char* fn) {
2297 2320
    SectionReader tmp(fn);
2298 2321
    return tmp;
2299 2322
  }
2300 2323

	
2301 2324
  /// \ingroup lemon_io
2302 2325
  ///
2303 2326
  /// \brief Reader for the contents of the \ref lgf-format "LGF" file
2304 2327
  ///
2305 2328
  /// This class can be used to read the sections, the map names and
2306 2329
  /// the attributes from a file. Usually, the LEMON programs know
2307 2330
  /// that, which type of graph, which maps and which attributes
2308 2331
  /// should be read from a file, but in general tools (like glemon)
2309 2332
  /// the contents of an LGF file should be guessed somehow. This class
2310 2333
  /// reads the graph and stores the appropriate information for
2311 2334
  /// reading the graph.
2312 2335
  ///
2313 2336
  ///\code
... ...
@@ -2317,104 +2340,108 @@
2317 2340
  /// // Does it contain any node section and arc section?
2318 2341
  /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
2319 2342
  ///   std::cerr << "Failure, cannot find graph." << std::endl;
2320 2343
  ///   return -1;
2321 2344
  /// }
2322 2345
  /// std::cout << "The name of the default node section: "
2323 2346
  ///           << contents.nodeSection(0) << std::endl;
2324 2347
  /// std::cout << "The number of the arc maps: "
2325 2348
  ///           << contents.arcMaps(0).size() << std::endl;
2326 2349
  /// std::cout << "The name of second arc map: "
2327 2350
  ///           << contents.arcMaps(0)[1] << std::endl;
2328 2351
  ///\endcode
2329 2352
  class LgfContents {
2330 2353
  private:
2331 2354

	
2332 2355
    std::istream* _is;
2333 2356
    bool local_is;
2334 2357

	
2335 2358
    std::vector<std::string> _node_sections;
2336 2359
    std::vector<std::string> _edge_sections;
2337 2360
    std::vector<std::string> _attribute_sections;
2338 2361
    std::vector<std::string> _extra_sections;
2339 2362

	
2340 2363
    std::vector<bool> _arc_sections;
2341 2364

	
2342 2365
    std::vector<std::vector<std::string> > _node_maps;
2343 2366
    std::vector<std::vector<std::string> > _edge_maps;
2344 2367

	
2345 2368
    std::vector<std::vector<std::string> > _attributes;
2346 2369

	
2347 2370

	
2348 2371
    int line_num;
2349 2372
    std::istringstream line;
2350 2373

	
2351 2374
  public:
2352 2375

	
2353 2376
    /// \brief Constructor
2354 2377
    ///
2355 2378
    /// Construct an \e LGF contents reader, which reads from the given
2356 2379
    /// input stream.
2357 2380
    LgfContents(std::istream& is)
2358 2381
      : _is(&is), local_is(false) {}
2359 2382

	
2360 2383
    /// \brief Constructor
2361 2384
    ///
2362 2385
    /// Construct an \e LGF contents reader, which reads from the given
2363 2386
    /// file.
2364 2387
    LgfContents(const std::string& fn)
2365
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2388
      : _is(new std::ifstream(fn.c_str())), local_is(true) {
2389
      if (!(*_is)) throw IoError("Cannot open file", fn);
2390
    }
2366 2391

	
2367 2392
    /// \brief Constructor
2368 2393
    ///
2369 2394
    /// Construct an \e LGF contents reader, which reads from the given
2370 2395
    /// file.
2371 2396
    LgfContents(const char* fn)
2372
      : _is(new std::ifstream(fn)), local_is(true) {}
2397
      : _is(new std::ifstream(fn)), local_is(true) {
2398
      if (!(*_is)) throw IoError("Cannot open file", fn);
2399
    }
2373 2400

	
2374 2401
    /// \brief Destructor
2375 2402
    ~LgfContents() {
2376 2403
      if (local_is) delete _is;
2377 2404
    }
2378 2405

	
2379 2406
  private:
2380 2407

	
2381 2408
    LgfContents(const LgfContents&);
2382 2409
    LgfContents& operator=(const LgfContents&);
2383 2410

	
2384 2411
  public:
2385 2412

	
2386 2413

	
2387 2414
    /// \name Node sections
2388 2415
    /// @{
2389 2416

	
2390 2417
    /// \brief Gives back the number of node sections in the file.
2391 2418
    ///
2392 2419
    /// Gives back the number of node sections in the file.
2393 2420
    int nodeSectionNum() const {
2394 2421
      return _node_sections.size();
2395 2422
    }
2396 2423

	
2397 2424
    /// \brief Returns the node section name at the given position.
2398 2425
    ///
2399 2426
    /// Returns the node section name at the given position.
2400 2427
    const std::string& nodeSection(int i) const {
2401 2428
      return _node_sections[i];
2402 2429
    }
2403 2430

	
2404 2431
    /// \brief Gives back the node maps for the given section.
2405 2432
    ///
2406 2433
    /// Gives back the node maps for the given section.
2407 2434
    const std::vector<std::string>& nodeMapNames(int i) const {
2408 2435
      return _node_maps[i];
2409 2436
    }
2410 2437

	
2411 2438
    /// @}
2412 2439

	
2413 2440
    /// \name Arc/Edge sections
2414 2441
    /// @{
2415 2442

	
2416 2443
    /// \brief Gives back the number of arc/edge sections in the file.
2417 2444
    ///
2418 2445
    /// Gives back the number of arc/edge sections in the file.
2419 2446
    /// \note It is synonym of \c edgeSectionNum().
2420 2447
    int arcSectionNum() const {
Ignore white space 96 line context
... ...
@@ -10,97 +10,97 @@
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() {}
... ...
@@ -158,117 +158,117 @@
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);
... ...
@@ -417,105 +417,109 @@
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(const Digraph& digraph, std::ostream& os = std::cout)
456 456
      : _os(&os), 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 Digraph& digraph, const std::string& fn)
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("Cannot write file", fn);
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 Digraph& digraph, const char* fn)
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("Cannot write file", fn);
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<>(const Digraph& digraph,
500 504
                                                  std::ostream& os);
501 505
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
502 506
                                                  const std::string& fn);
503 507
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
504 508
                                                  const char *fn);
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;
... ...
@@ -974,105 +978,109 @@
974 978
  private:
975 979

	
976 980

	
977 981
    std::ostream* _os;
978 982
    bool local_os;
979 983

	
980 984
    const Graph& _graph;
981 985

	
982 986
    std::string _nodes_caption;
983 987
    std::string _edges_caption;
984 988
    std::string _attributes_caption;
985 989

	
986 990
    typedef std::map<Node, std::string> NodeIndex;
987 991
    NodeIndex _node_index;
988 992
    typedef std::map<Edge, std::string> EdgeIndex;
989 993
    EdgeIndex _edge_index;
990 994

	
991 995
    typedef std::vector<std::pair<std::string,
992 996
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
993 997
    NodeMaps _node_maps;
994 998

	
995 999
    typedef std::vector<std::pair<std::string,
996 1000
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
997 1001
    EdgeMaps _edge_maps;
998 1002

	
999 1003
    typedef std::vector<std::pair<std::string,
1000 1004
      _writer_bits::ValueStorageBase*> > Attributes;
1001 1005
    Attributes _attributes;
1002 1006

	
1003 1007
    bool _skip_nodes;
1004 1008
    bool _skip_edges;
1005 1009

	
1006 1010
  public:
1007 1011

	
1008 1012
    /// \brief Constructor
1009 1013
    ///
1010 1014
    /// Construct a directed graph writer, which writes to the given
1011 1015
    /// output stream.
1012 1016
    GraphWriter(const Graph& graph, std::ostream& os = std::cout)
1013 1017
      : _os(&os), local_os(false), _graph(graph),
1014 1018
        _skip_nodes(false), _skip_edges(false) {}
1015 1019

	
1016 1020
    /// \brief Constructor
1017 1021
    ///
1018 1022
    /// Construct a directed graph writer, which writes to the given
1019 1023
    /// output file.
1020 1024
    GraphWriter(const Graph& graph, const std::string& fn)
1021 1025
      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
1022
        _skip_nodes(false), _skip_edges(false) {}
1026
        _skip_nodes(false), _skip_edges(false) {
1027
      if (!(*_os)) throw IoError("Cannot write file", fn);
1028
    }
1023 1029

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

	
1032 1040
    /// \brief Destructor
1033 1041
    ~GraphWriter() {
1034 1042
      for (typename NodeMaps::iterator it = _node_maps.begin();
1035 1043
           it != _node_maps.end(); ++it) {
1036 1044
        delete it->second;
1037 1045
      }
1038 1046

	
1039 1047
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1040 1048
           it != _edge_maps.end(); ++it) {
1041 1049
        delete it->second;
1042 1050
      }
1043 1051

	
1044 1052
      for (typename Attributes::iterator it = _attributes.begin();
1045 1053
           it != _attributes.end(); ++it) {
1046 1054
        delete it->second;
1047 1055
      }
1048 1056

	
1049 1057
      if (local_os) {
1050 1058
        delete _os;
1051 1059
      }
1052 1060
    }
1053 1061

	
1054 1062
  private:
1055 1063

	
1056 1064
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1057 1065
                                            std::ostream& os);
1058 1066
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1059 1067
                                            const std::string& fn);
1060 1068
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1061 1069
                                            const char *fn);
1062 1070

	
1063 1071
    GraphWriter(GraphWriter& other)
1064 1072
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
1065 1073
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1066 1074

	
1067 1075
      other._os = 0;
1068 1076
      other.local_os = false;
1069 1077

	
1070 1078
      _node_index.swap(other._node_index);
1071 1079
      _edge_index.swap(other._edge_index);
1072 1080

	
1073 1081
      _node_maps.swap(other._node_maps);
1074 1082
      _edge_maps.swap(other._edge_maps);
1075 1083
      _attributes.swap(other._attributes);
1076 1084

	
1077 1085
      _nodes_caption = other._nodes_caption;
1078 1086
      _edges_caption = other._edges_caption;
... ...
@@ -1533,103 +1541,107 @@
1533 1541
  /// \relates GraphWriter
1534 1542
  template <typename Graph>
1535 1543
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
1536 1544
    GraphWriter<Graph> tmp(graph, fn);
1537 1545
    return tmp;
1538 1546
  }
1539 1547

	
1540 1548
  class SectionWriter;
1541 1549

	
1542 1550
  SectionWriter sectionWriter(std::istream& is);
1543 1551
  SectionWriter sectionWriter(const std::string& fn);
1544 1552
  SectionWriter sectionWriter(const char* fn);
1545 1553

	
1546 1554
  /// \ingroup lemon_io
1547 1555
  ///
1548 1556
  /// \brief Section writer class
1549 1557
  ///
1550 1558
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
1551 1559
  /// which contain any data in arbitrary format. Such sections can be
1552 1560
  /// written with this class. A writing rule can be added to the
1553 1561
  /// class with two different functions. With the \c sectionLines()
1554 1562
  /// function a generator can write the section line-by-line, while
1555 1563
  /// with the \c sectionStream() member the section can be written to
1556 1564
  /// an output stream.
1557 1565
  class SectionWriter {
1558 1566
  private:
1559 1567

	
1560 1568
    std::ostream* _os;
1561 1569
    bool local_os;
1562 1570

	
1563 1571
    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
1564 1572
    Sections;
1565 1573

	
1566 1574
    Sections _sections;
1567 1575

	
1568 1576
  public:
1569 1577

	
1570 1578
    /// \brief Constructor
1571 1579
    ///
1572 1580
    /// Construct a section writer, which writes to the given output
1573 1581
    /// stream.
1574 1582
    SectionWriter(std::ostream& os)
1575 1583
      : _os(&os), local_os(false) {}
1576 1584

	
1577 1585
    /// \brief Constructor
1578 1586
    ///
1579 1587
    /// Construct a section writer, which writes into the given file.
1580 1588
    SectionWriter(const std::string& fn)
1581
      : _os(new std::ofstream(fn.c_str())), local_os(true) {}
1589
      : _os(new std::ofstream(fn.c_str())), local_os(true) {
1590
      if (!(*_os)) throw IoError("Cannot write file", fn);
1591
    }
1582 1592

	
1583 1593
    /// \brief Constructor
1584 1594
    ///
1585 1595
    /// Construct a section writer, which writes into the given file.
1586 1596
    SectionWriter(const char* fn)
1587
      : _os(new std::ofstream(fn)), local_os(true) {}
1597
      : _os(new std::ofstream(fn)), local_os(true) {
1598
      if (!(*_os)) throw IoError("Cannot write file", fn);
1599
    }
1588 1600

	
1589 1601
    /// \brief Destructor
1590 1602
    ~SectionWriter() {
1591 1603
      for (Sections::iterator it = _sections.begin();
1592 1604
           it != _sections.end(); ++it) {
1593 1605
        delete it->second;
1594 1606
      }
1595 1607

	
1596 1608
      if (local_os) {
1597 1609
        delete _os;
1598 1610
      }
1599 1611

	
1600 1612
    }
1601 1613

	
1602 1614
  private:
1603 1615

	
1604 1616
    friend SectionWriter sectionWriter(std::ostream& os);
1605 1617
    friend SectionWriter sectionWriter(const std::string& fn);
1606 1618
    friend SectionWriter sectionWriter(const char* fn);
1607 1619

	
1608 1620
    SectionWriter(SectionWriter& other)
1609 1621
      : _os(other._os), local_os(other.local_os) {
1610 1622

	
1611 1623
      other._os = 0;
1612 1624
      other.local_os = false;
1613 1625

	
1614 1626
      _sections.swap(other._sections);
1615 1627
    }
1616 1628

	
1617 1629
    SectionWriter& operator=(const SectionWriter&);
1618 1630

	
1619 1631
  public:
1620 1632

	
1621 1633
    /// \name Section writers
1622 1634
    /// @{
1623 1635

	
1624 1636
    /// \brief Add a section writer with line oriented writing
1625 1637
    ///
1626 1638
    /// The first parameter is the type descriptor of the section, the
1627 1639
    /// second is a generator with std::string values. At the writing
1628 1640
    /// process, the returned \c std::string will be written into the
1629 1641
    /// output file until it is an empty string.
1630 1642
    ///
1631 1643
    /// For example, an integer vector is written into a section.
1632 1644
    ///\code
1633 1645
    ///  @numbers
1634 1646
    ///  12 45 23 78
1635 1647
    ///  4 28 38 28
0 comments (0 inline)