gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Simplifying exceptions - Using asserts instead of exceptions for unitialized parameters - Only the IO exceptions are used in the lemon - DataFormatError is renamed to FormatError - The IoError is used for file access errors
0 11 0
default
11 files changed with 380 insertions and 511 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -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("digraph.lgf", g). // read the directed graph into g
48 48
      arcMap("capacity", cap).       // read the 'capacity' arc map into cap
49 49
      node("source", s).             // read 'source' node to s
50 50
      node("target", t).             // read 'target' node to t
51 51
      run();
52
  } catch (DataFormatError& error) { // check if there was any error
52
  } catch (Exception& error) { // check if there was any error
53 53
    std::cerr << "Error: " << error.what() << std::endl;
54 54
    return -1;
55 55
  }
56 56

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

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

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

	
69 69
  return 0;
70 70
}
Ignore white space 6 line context
... ...
@@ -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 = BfsDefaultTraits<_Digraph> >
1322 1316
#endif
1323 1317
  class BfsVisit {
1324 1318
  public:
1325 1319

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

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

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

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

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

	
1350 1332
  private:
1351 1333

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

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

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

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

	
1377 1359
  protected:
1378 1360

	
1379 1361
    BfsVisit() {}
1380 1362

	
1381 1363
  public:
1382 1364

	
1383 1365
    typedef BfsVisit Create;
1384 1366

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

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

	
1406 1389
  public:
1407 1390

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

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

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

	
1439 1422
  public:
1440 1423

	
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 = DfsDefaultTraits<_Digraph> >
1269 1262
#endif
1270 1263
  class DfsVisit {
1271 1264
  public:
1272 1265

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

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

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

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

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

	
1297 1278
  private:
1298 1279

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

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

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

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

	
1324 1305
  protected:
1325 1306

	
1326 1307
    DfsVisit() {}
1327 1308

	
1328 1309
  public:
1329 1310

	
1330 1311
    typedef DfsVisit Create;
1331 1312

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

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

	
1353 1335
  public:
1354 1336

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

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

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

	
1386 1368
  public:
1387 1369

	
Ignore white space 96 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
44
    ///\e Constructor
172 45
    Exception() {}
173
    ///\e
46
    ///\e Virtual destructor
174 47
    virtual ~Exception() throw() {}
175
    ///\e
48
    ///\e A short description of the exception
176 49
    virtual const char* what() const throw() {
177 50
      return "lemon::Exception";
178 51
    }
179 52
  };
180 53

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
193 153
  };
194 154

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

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

	
206

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
325

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

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

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

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

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

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

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

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

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

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

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

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

	
414 272
  /// @}
415 273

	
416 274
}
417 275

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

	
19 19
#ifndef LEMON_GRAPH_TO_EPS_H
20 20
#define LEMON_GRAPH_TO_EPS_H
21 21

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

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

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

	
44 45

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

	
49 50
namespace lemon {
50 51

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

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

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

	
80 81

	
81 82
  const Graph &g;
82 83

	
83 84
  std::ostream& os;
84 85

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

	
90 91
  ConstMap<typename Graph::Node,Color > _nodeColors;
... ...
@@ -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(file_name, "Cannot write file");
1174
  }
1169 1175
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1170
    (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name),true));
1176
    (DefaultGraphToEpsTraits<G>(g,*os,true));
1171 1177
}
1172 1178

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

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

	
1189 1200
} //END OF NAMESPACE LEMON
1190 1201

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

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

	
458 460
  private:
459 461

	
460 462

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

	
464 467
    Digraph& _digraph;
465 468

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

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

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

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

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

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

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

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

	
496 499
  public:
497 500

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

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

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

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

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

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

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

	
546 555
    }
547 556

	
548 557
  private:
549 558

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

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

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

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

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

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

	
810 819
    /// @}
811 820

	
812 821
  private:
813 822

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

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

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

	
839 848
    void readNodes() {
840 849

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

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

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

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

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

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

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

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

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

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

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

	
932 941
    void readArcs() {
933 942

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

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

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

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

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

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

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

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

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

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

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

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

	
1009 1018
          typename NodeIndex::iterator it;
1010 1019

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

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

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

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

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

	
1053 1062
    void readAttributes() {
1054 1063

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

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

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

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

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

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

	
1101 1110
  public:
1102 1111

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

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

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

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

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

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

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

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

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

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

	
1172 1182
    }
1173 1183

	
1174 1184
    /// @}
1175 1185

	
1176 1186
  };
1177 1187

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

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

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

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

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

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

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

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

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

	
1243 1253
  private:
1244 1254

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

	
1248 1259
    Graph& _graph;
1249 1260

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

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

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

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

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

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

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

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

	
1280 1291
  public:
1281 1292

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

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

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

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

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

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

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

	
1330 1347
    }
1331 1348

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

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

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

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

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

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

	
1638 1655
    /// @}
1639 1656

	
1640 1657
  private:
1641 1658

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

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

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

	
1667 1684
    void readNodes() {
1668 1685

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

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

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

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

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

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

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

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

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

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

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

	
1760 1777
    void readEdges() {
1761 1778

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

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

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

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

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

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

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

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

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

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

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

	
1834 1851
        Edge e;
1835 1852
        if (!_use_edges) {
1836 1853

	
1837 1854
          typename NodeIndex::iterator it;
1838 1855

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

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

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

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

	
1875 1892
      }
1876 1893
      if (readSuccess()) {
1877 1894
        line.putback(c);
1878 1895
      }
1879 1896
    }
1880 1897

	
1881 1898
    void readAttributes() {
1882 1899

	
1883 1900
      std::set<std::string> read_attr;
1884 1901

	
1885 1902
      char c;
1886 1903
      while (readLine() && line >> c && c != '@') {
1887 1904
        line.putback(c);
1888 1905

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

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

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

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

	
1929 1946
  public:
1930 1947

	
1931 1948
    /// \name Execution of the reader
1932 1949
    /// @{
1933 1950

	
1934 1951
    /// \brief Start the batch processing
1935 1952
    ///
1936 1953
    /// This function starts the batch processing
1937 1954
    void run() {
1938 1955

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

	
1941 1958
      bool nodes_done = _skip_nodes;
1942 1959
      bool edges_done = _skip_edges;
1943 1960
      bool attributes_done = false;
1944 1961

	
1945 1962
      line_num = 0;
1946 1963
      readLine();
1947 1964
      skipSection();
1948 1965

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

	
1957 1974
          if (line >> c)
1958
            throw DataFormatError("Extra character on the end of line");
1975
            throw FormatError("Extra character on the end of line");
1959 1976

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

	
1986 2004
      if (!nodes_done) {
1987
        throw DataFormatError("Section @nodes not found");
2005
        throw FormatError("Section @nodes not found");
1988 2006
      }
1989 2007

	
1990 2008
      if (!edges_done) {
1991
        throw DataFormatError("Section @edges not found");
2009
        throw FormatError("Section @edges not found");
1992 2010
      }
1993 2011

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

	
1998 2016
    }
1999 2017

	
2000 2018
    /// @}
2001 2019

	
2002 2020
  };
2003 2021

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

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

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

	
2035 2053
  class SectionReader;
2036 2054

	
2037 2055
  SectionReader sectionReader(std::istream& is);
2038 2056
  SectionReader sectionReader(const std::string& fn);
2039 2057
  SectionReader sectionReader(const char* fn);
2040 2058

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

	
2055 2073
    std::istream* _is;
2056 2074
    bool local_is;
2075
    std::string _filename;
2057 2076

	
2058 2077
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2059 2078
    Sections _sections;
2060 2079

	
2061 2080
    int line_num;
2062 2081
    std::istringstream line;
2063 2082

	
2064 2083
  public:
2065 2084

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

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

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

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

	
2092 2117
      if (local_is) {
2093 2118
        delete _is;
2094 2119
      }
2095 2120

	
2096 2121
    }
2097 2122

	
2098 2123
  private:
2099 2124

	
2100 2125
    friend SectionReader sectionReader(std::istream& is);
2101 2126
    friend SectionReader sectionReader(const std::string& fn);
2102 2127
    friend SectionReader sectionReader(const char* fn);
2103 2128

	
2104 2129
    SectionReader(SectionReader& other)
2105 2130
      : _is(other._is), local_is(other.local_is) {
2106 2131

	
2107 2132
      other._is = 0;
2108 2133
      other.local_is = false;
2109 2134

	
2110 2135
      _sections.swap(other._sections);
2111 2136
    }
2112 2137

	
2113 2138
    SectionReader& operator=(const SectionReader&);
2114 2139

	
2115 2140
  public:
2116 2141

	
2117 2142
    /// \name Section readers
2118 2143
    /// @{
2119 2144

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

	
2199 2224
    bool readSuccess() {
2200 2225
      return static_cast<bool>(*_is);
2201 2226
    }
2202 2227

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

	
2211 2236
  public:
2212 2237

	
2213 2238

	
2214 2239
    /// \name Execution of the reader
2215 2240
    /// @{
2216 2241

	
2217 2242
    /// \brief Start the batch processing
2218 2243
    ///
2219 2244
    /// This function starts the batch processing.
2220 2245
    void run() {
2221 2246

	
2222 2247
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2223 2248

	
2224 2249
      std::set<std::string> extra_sections;
2225 2250

	
2226 2251
      line_num = 0;
2227 2252
      readLine();
2228 2253
      skipSection();
2229 2254

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

	
2238 2263
          if (line >> c)
2239
            throw DataFormatError("Extra character on the end of line");
2264
            throw FormatError("Extra character on the end of line");
2240 2265

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

	
2268 2294
    /// @}
2269 2295

	
2270 2296
  };
2271 2297

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

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

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

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

	
2330 2356
    std::istream* _is;
2331 2357
    bool local_is;
2332 2358

	
2333 2359
    std::vector<std::string> _node_sections;
2334 2360
    std::vector<std::string> _edge_sections;
2335 2361
    std::vector<std::string> _attribute_sections;
2336 2362
    std::vector<std::string> _extra_sections;
2337 2363

	
2338 2364
    std::vector<bool> _arc_sections;
2339 2365

	
2340 2366
    std::vector<std::vector<std::string> > _node_maps;
2341 2367
    std::vector<std::vector<std::string> > _edge_maps;
2342 2368

	
2343 2369
    std::vector<std::vector<std::string> > _attributes;
2344 2370

	
2345 2371

	
2346 2372
    int line_num;
2347 2373
    std::istringstream line;
2348 2374

	
2349 2375
  public:
2350 2376

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

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

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

	
2372 2402
    /// \brief Destructor
2373 2403
    ~LgfContents() {
2374 2404
      if (local_is) delete _is;
2375 2405
    }
2376 2406

	
2377 2407
  private:
2378 2408

	
2379 2409
    LgfContents(const LgfContents&);
2380 2410
    LgfContents& operator=(const LgfContents&);
2381 2411

	
2382 2412
  public:
2383 2413

	
2384 2414

	
2385 2415
    /// \name Node sections
2386 2416
    /// @{
2387 2417

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

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

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

	
2409 2439
    /// @}
2410 2440

	
2411 2441
    /// \name Arc/Edge sections
2412 2442
    /// @{
2413 2443

	
2414 2444
    /// \brief Gives back the number of arc/edge sections in the file.
2415 2445
    ///
2416 2446
    /// Gives back the number of arc/edge sections in the file.
2417 2447
    /// \note It is synonym of \c edgeSectionNum().
2418 2448
    int arcSectionNum() const {
Ignore white space 6 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(std::ostream& is, const Digraph& digraph)
456 456
      : _os(&is), local_os(false), _digraph(digraph),
457 457
        _skip_nodes(false), _skip_arcs(false) {}
458 458

	
459 459
    /// \brief Constructor
460 460
    ///
461 461
    /// Construct a directed graph writer, which writes to the given
462 462
    /// output file.
463 463
    DigraphWriter(const std::string& fn, const Digraph& digraph)
464 464
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
465
        _skip_nodes(false), _skip_arcs(false) {}
465
        _skip_nodes(false), _skip_arcs(false) {
466
      if (!(*_os)) throw IoError(fn, "Cannot write file");
467
    }
466 468

	
467 469
    /// \brief Constructor
468 470
    ///
469 471
    /// Construct a directed graph writer, which writes to the given
470 472
    /// output file.
471 473
    DigraphWriter(const char* fn, const Digraph& digraph)
472 474
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
473
        _skip_nodes(false), _skip_arcs(false) {}
475
        _skip_nodes(false), _skip_arcs(false) {
476
      if (!(*_os)) throw IoError(fn, "Cannot write file");
477
    }
474 478

	
475 479
    /// \brief Destructor
476 480
    ~DigraphWriter() {
477 481
      for (typename NodeMaps::iterator it = _node_maps.begin();
478 482
           it != _node_maps.end(); ++it) {
479 483
        delete it->second;
480 484
      }
481 485

	
482 486
      for (typename ArcMaps::iterator it = _arc_maps.begin();
483 487
           it != _arc_maps.end(); ++it) {
484 488
        delete it->second;
485 489
      }
486 490

	
487 491
      for (typename Attributes::iterator it = _attributes.begin();
488 492
           it != _attributes.end(); ++it) {
489 493
        delete it->second;
490 494
      }
491 495

	
492 496
      if (local_os) {
493 497
        delete _os;
494 498
      }
495 499
    }
496 500

	
497 501
  private:
498 502

	
499 503
    friend DigraphWriter<Digraph> digraphWriter<>(std::ostream& os,
500 504
                                                  const Digraph& digraph);
501 505
    friend DigraphWriter<Digraph> digraphWriter<>(const std::string& fn,
502 506
                                                  const Digraph& digraph);
503 507
    friend DigraphWriter<Digraph> digraphWriter<>(const char *fn,
504 508
                                                  const Digraph& digraph);
505 509

	
506 510
    DigraphWriter(DigraphWriter& other)
507 511
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
508 512
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
509 513

	
510 514
      other._os = 0;
511 515
      other.local_os = false;
512 516

	
513 517
      _node_index.swap(other._node_index);
514 518
      _arc_index.swap(other._arc_index);
515 519

	
516 520
      _node_maps.swap(other._node_maps);
517 521
      _arc_maps.swap(other._arc_maps);
518 522
      _attributes.swap(other._attributes);
519 523

	
520 524
      _nodes_caption = other._nodes_caption;
521 525
      _arcs_caption = other._arcs_caption;
... ...
@@ -973,105 +977,109 @@
973 977
  private:
974 978

	
975 979

	
976 980
    std::ostream* _os;
977 981
    bool local_os;
978 982

	
979 983
    const Graph& _graph;
980 984

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

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

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

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

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

	
1002 1006
    bool _skip_nodes;
1003 1007
    bool _skip_edges;
1004 1008

	
1005 1009
  public:
1006 1010

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

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

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

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

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

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

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

	
1053 1061
  private:
1054 1062

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

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

	
1066 1074
      other._os = 0;
1067 1075
      other.local_os = false;
1068 1076

	
1069 1077
      _node_index.swap(other._node_index);
1070 1078
      _edge_index.swap(other._edge_index);
1071 1079

	
1072 1080
      _node_maps.swap(other._node_maps);
1073 1081
      _edge_maps.swap(other._edge_maps);
1074 1082
      _attributes.swap(other._attributes);
1075 1083

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

	
1538 1546
  class SectionWriter;
1539 1547

	
1540 1548
  SectionWriter sectionWriter(std::istream& is);
1541 1549
  SectionWriter sectionWriter(const std::string& fn);
1542 1550
  SectionWriter sectionWriter(const char* fn);
1543 1551

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

	
1558 1566
    std::ostream* _os;
1559 1567
    bool local_os;
1560 1568

	
1561 1569
    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
1562 1570
    Sections;
1563 1571

	
1564 1572
    Sections _sections;
1565 1573

	
1566 1574
  public:
1567 1575

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

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

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

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

	
1594 1606
      if (local_os) {
1595 1607
        delete _os;
1596 1608
      }
1597 1609

	
1598 1610
    }
1599 1611

	
1600 1612
  private:
1601 1613

	
1602 1614
    friend SectionWriter sectionWriter(std::ostream& os);
1603 1615
    friend SectionWriter sectionWriter(const std::string& fn);
1604 1616
    friend SectionWriter sectionWriter(const char* fn);
1605 1617

	
1606 1618
    SectionWriter(SectionWriter& other)
1607 1619
      : _os(other._os), local_os(other.local_os) {
1608 1620

	
1609 1621
      other._os = 0;
1610 1622
      other.local_os = false;
1611 1623

	
1612 1624
      _sections.swap(other._sections);
1613 1625
    }
1614 1626

	
1615 1627
    SectionWriter& operator=(const SectionWriter&);
1616 1628

	
1617 1629
  public:
1618 1630

	
1619 1631
    /// \name Section writers
1620 1632
    /// @{
1621 1633

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