gravatar
ladanyi@tmit.bme.hu
ladanyi@tmit.bme.hu
Fix compilation with Visual Studio 2005.
0 2 0
default
2 files changed with 93 insertions and 135 deletions:
↑ Collapse diff ↑
Show white space 96 line context
... ...
@@ -346,105 +346,127 @@
346 346
          } else if (c == '#') {
347 347
            getline(is, line);
348 348
            ++line_num;
349 349
          } else if (!isWhiteSpace(c)) {
350 350
            is.putback(c);
351 351
            getline(is, line);
352 352
            _functor(line);
353 353
            ++line_num;
354 354
          }
355 355
        }
356 356
        if (is) is.putback(c);
357 357
        else if (is.eof()) is.clear();
358 358
      }
359 359
    };
360 360

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

	
365 365
      Functor _functor;
366 366

	
367 367
    public:
368 368

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

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

	
389 389
  }
390 390

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

	
394
  /// \brief Return a \ref DigraphReader class
395
  ///
396
  /// This function just returns a \ref DigraphReader class.
397
  /// \relates DigraphReader
394 398
  template <typename Digraph>
395 399
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
396
                                       std::istream& is = std::cin);
397

	
400
                                       std::istream& is = std::cin) {
401
    DigraphReader<Digraph> tmp(digraph, is);
402
    return tmp;
403
  }
404

	
405
  /// \brief Return a \ref DigraphReader class
406
  ///
407
  /// This function just returns a \ref DigraphReader class.
408
  /// \relates DigraphReader
398 409
  template <typename Digraph>
399
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const std::string& fn);
400

	
410
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
411
                                       const std::string& fn) {
412
    DigraphReader<Digraph> tmp(digraph, fn);
413
    return tmp;
414
  }
415

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

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

	
1147 1169
          if (section == "nodes" && !nodes_done) {
1148 1170
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1149 1171
              readNodes();
1150 1172
              nodes_done = true;
1151 1173
            }
1152 1174
          } else if ((section == "arcs" || section == "edges") &&
1153 1175
                     !arcs_done) {
1154 1176
            if (_arcs_caption.empty() || _arcs_caption == caption) {
1155 1177
              readArcs();
1156 1178
              arcs_done = true;
1157 1179
            }
1158 1180
          } else if (section == "attributes" && !attributes_done) {
1159 1181
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1160 1182
              readAttributes();
1161 1183
              attributes_done = true;
1162 1184
            }
1163 1185
          } else {
1164 1186
            readLine();
1165 1187
            skipSection();
1166 1188
          }
1167 1189
        } catch (FormatError& error) {
1168 1190
          error.line(line_num);
1169 1191
          error.file(_filename);
1170 1192
          throw;
1171 1193
        }
1172 1194
      }
1173 1195

	
1174 1196
      if (!nodes_done) {
1175 1197
        throw FormatError("Section @nodes not found");
1176 1198
      }
1177 1199

	
1178 1200
      if (!arcs_done) {
1179 1201
        throw FormatError("Section @arcs not found");
1180 1202
      }
1181 1203

	
1182 1204
      if (!attributes_done && !_attributes.empty()) {
1183 1205
        throw FormatError("Section @attributes not found");
1184 1206
      }
1185 1207

	
1186 1208
    }
1187 1209

	
1188 1210
    /// @}
1189 1211

	
1190 1212
  };
1191 1213

	
1192
  /// \brief Return a \ref DigraphReader class
1214
  template <typename Graph>
1215
  class GraphReader;
1216

	
1217
  /// \brief Return a \ref GraphReader class
1193 1218
  ///
1194
  /// This function just returns a \ref DigraphReader class.
1195
  /// \relates DigraphReader
1196
  template <typename Digraph>
1197
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
1198
                                       std::istream& is = std::cin) {
1199
    DigraphReader<Digraph> tmp(digraph, is);
1219
  /// This function just returns a \ref GraphReader class.
1220
  /// \relates GraphReader
1221
  template <typename Graph>
1222
  GraphReader<Graph> graphReader(Graph& graph, std::istream& is = std::cin) {
1223
    GraphReader<Graph> tmp(graph, is);
1200 1224
    return tmp;
1201 1225
  }
1202 1226

	
1203
  /// \brief Return a \ref DigraphReader class
1227
  /// \brief Return a \ref GraphReader class
1204 1228
  ///
1205
  /// This function just returns a \ref DigraphReader class.
1206
  /// \relates DigraphReader
1207
  template <typename Digraph>
1208
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
1209
                                       const std::string& fn) {
1210
    DigraphReader<Digraph> tmp(digraph, fn);
1229
  /// This function just returns a \ref GraphReader class.
1230
  /// \relates GraphReader
1231
  template <typename Graph>
1232
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
1233
    GraphReader<Graph> tmp(graph, fn);
1211 1234
    return tmp;
1212 1235
  }
1213 1236

	
1214
  /// \brief Return a \ref DigraphReader class
1237
  /// \brief Return a \ref GraphReader class
1215 1238
  ///
1216
  /// This function just returns a \ref DigraphReader class.
1217
  /// \relates DigraphReader
1218
  template <typename Digraph>
1219
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
1220
    DigraphReader<Digraph> tmp(digraph, fn);
1239
  /// This function just returns a \ref GraphReader class.
1240
  /// \relates GraphReader
1241
  template <typename Graph>
1242
  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
1243
    GraphReader<Graph> tmp(graph, fn);
1221 1244
    return tmp;
1222 1245
  }
1223 1246

	
1224
  template <typename Graph>
1225
  class GraphReader;
1226

	
1227
  template <typename Graph>
1228
  GraphReader<Graph> graphReader(Graph& graph,
1229
                                 std::istream& is = std::cin);
1230

	
1231
  template <typename Graph>
1232
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
1233

	
1234
  template <typename Graph>
1235
  GraphReader<Graph> graphReader(Graph& graph, const char *fn);
1236

	
1237 1247
  /// \ingroup lemon_io
1238 1248
  ///
1239 1249
  /// \brief \ref lgf-format "LGF" reader for undirected graphs
1240 1250
  ///
1241 1251
  /// This utility reads an \ref lgf-format "LGF" file.
1242 1252
  ///
1243 1253
  /// It can be used almost the same way as \c DigraphReader.
1244 1254
  /// The only difference is that this class can handle edges and
1245 1255
  /// edge maps as well as arcs and arc maps.
1246 1256
  ///
1247 1257
  /// The columns in the \c \@edges (or \c \@arcs) section are the
1248 1258
  /// edge maps. However, if there are two maps with the same name
1249 1259
  /// prefixed with \c '+' and \c '-', then these can be read into an
1250 1260
  /// arc map.  Similarly, an attribute can be read into an arc, if
1251 1261
  /// it's value is an edge label prefixed with \c '+' or \c '-'.
1252 1262
  template <typename _Graph>
1253 1263
  class GraphReader {
1254 1264
  public:
1255 1265

	
1256 1266
    typedef _Graph Graph;
1257 1267
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1258 1268

	
1259 1269
  private:
1260 1270

	
1261 1271
    std::istream* _is;
1262 1272
    bool local_is;
1263 1273
    std::string _filename;
1264 1274

	
1265 1275
    Graph& _graph;
1266 1276

	
1267 1277
    std::string _nodes_caption;
1268 1278
    std::string _edges_caption;
1269 1279
    std::string _attributes_caption;
1270 1280

	
1271 1281
    typedef std::map<std::string, Node> NodeIndex;
1272 1282
    NodeIndex _node_index;
1273 1283
    typedef std::map<std::string, Edge> EdgeIndex;
1274 1284
    EdgeIndex _edge_index;
1275 1285

	
1276 1286
    typedef std::vector<std::pair<std::string,
1277 1287
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1278 1288
    NodeMaps _node_maps;
1279 1289

	
1280 1290
    typedef std::vector<std::pair<std::string,
1281 1291
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1282 1292
    EdgeMaps _edge_maps;
1283 1293

	
1284 1294
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
... ...
@@ -1986,126 +1996,96 @@
1986 1996
          if (line >> c)
1987 1997
            throw FormatError("Extra character at the end of line");
1988 1998

	
1989 1999
          if (section == "nodes" && !nodes_done) {
1990 2000
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1991 2001
              readNodes();
1992 2002
              nodes_done = true;
1993 2003
            }
1994 2004
          } else if ((section == "edges" || section == "arcs") &&
1995 2005
                     !edges_done) {
1996 2006
            if (_edges_caption.empty() || _edges_caption == caption) {
1997 2007
              readEdges();
1998 2008
              edges_done = true;
1999 2009
            }
2000 2010
          } else if (section == "attributes" && !attributes_done) {
2001 2011
            if (_attributes_caption.empty() || _attributes_caption == caption) {
2002 2012
              readAttributes();
2003 2013
              attributes_done = true;
2004 2014
            }
2005 2015
          } else {
2006 2016
            readLine();
2007 2017
            skipSection();
2008 2018
          }
2009 2019
        } catch (FormatError& error) {
2010 2020
          error.line(line_num);
2011 2021
          error.file(_filename);
2012 2022
          throw;
2013 2023
        }
2014 2024
      }
2015 2025

	
2016 2026
      if (!nodes_done) {
2017 2027
        throw FormatError("Section @nodes not found");
2018 2028
      }
2019 2029

	
2020 2030
      if (!edges_done) {
2021 2031
        throw FormatError("Section @edges not found");
2022 2032
      }
2023 2033

	
2024 2034
      if (!attributes_done && !_attributes.empty()) {
2025 2035
        throw FormatError("Section @attributes not found");
2026 2036
      }
2027 2037

	
2028 2038
    }
2029 2039

	
2030 2040
    /// @}
2031 2041

	
2032 2042
  };
2033 2043

	
2034
  /// \brief Return a \ref GraphReader class
2035
  ///
2036
  /// This function just returns a \ref GraphReader class.
2037
  /// \relates GraphReader
2038
  template <typename Graph>
2039
  GraphReader<Graph> graphReader(Graph& graph, std::istream& is = std::cin) {
2040
    GraphReader<Graph> tmp(graph, is);
2041
    return tmp;
2042
  }
2043

	
2044
  /// \brief Return a \ref GraphReader class
2045
  ///
2046
  /// This function just returns a \ref GraphReader class.
2047
  /// \relates GraphReader
2048
  template <typename Graph>
2049
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
2050
    GraphReader<Graph> tmp(graph, fn);
2051
    return tmp;
2052
  }
2053

	
2054
  /// \brief Return a \ref GraphReader class
2055
  ///
2056
  /// This function just returns a \ref GraphReader class.
2057
  /// \relates GraphReader
2058
  template <typename Graph>
2059
  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
2060
    GraphReader<Graph> tmp(graph, fn);
2061
    return tmp;
2062
  }
2063

	
2064 2044
  class SectionReader;
2065 2045

	
2066 2046
  SectionReader sectionReader(std::istream& is);
2067 2047
  SectionReader sectionReader(const std::string& fn);
2068 2048
  SectionReader sectionReader(const char* fn);
2069 2049

	
2070 2050
  /// \ingroup lemon_io
2071 2051
  ///
2072 2052
  /// \brief Section reader class
2073 2053
  ///
2074 2054
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
2075 2055
  /// which contain any data in arbitrary format. Such sections can be
2076 2056
  /// read with this class. A reading rule can be added to the class
2077 2057
  /// with two different functions. With the \c sectionLines() function a
2078 2058
  /// functor can process the section line-by-line, while with the \c
2079 2059
  /// sectionStream() member the section can be read from an input
2080 2060
  /// stream.
2081 2061
  class SectionReader {
2082 2062
  private:
2083 2063

	
2084 2064
    std::istream* _is;
2085 2065
    bool local_is;
2086 2066
    std::string _filename;
2087 2067

	
2088 2068
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2089 2069
    Sections _sections;
2090 2070

	
2091 2071
    int line_num;
2092 2072
    std::istringstream line;
2093 2073

	
2094 2074
  public:
2095 2075

	
2096 2076
    /// \brief Constructor
2097 2077
    ///
2098 2078
    /// Construct a section reader, which reads from the given input
2099 2079
    /// stream.
2100 2080
    SectionReader(std::istream& is)
2101 2081
      : _is(&is), local_is(false) {}
2102 2082

	
2103 2083
    /// \brief Constructor
2104 2084
    ///
2105 2085
    /// Construct a section reader, which reads from the given file.
2106 2086
    SectionReader(const std::string& fn)
2107 2087
      : _is(new std::ifstream(fn.c_str())), local_is(true),
2108 2088
        _filename(fn) {
2109 2089
      if (!(*_is)) {
2110 2090
        delete _is;
2111 2091
        throw IoError("Cannot open file", fn);
Show white space 96 line context
... ...
@@ -306,107 +306,128 @@
306 306
      }
307 307
      return os;
308 308
    }
309 309

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

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

	
320 320
      Functor _functor;
321 321

	
322 322
    public:
323 323

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

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

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

	
337 337
      Functor _functor;
338 338

	
339 339
    public:
340 340

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

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

	
349 349
  }
350 350

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

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

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

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

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

	
869 890
    void writeAttributes() {
870 891
      if (_attributes.empty()) return;
871 892
      *_os << "@attributes";
872 893
      if (!_attributes_caption.empty()) {
873 894
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
874 895
      }
875 896
      *_os << std::endl;
876 897
      for (typename Attributes::iterator it = _attributes.begin();
877 898
           it != _attributes.end(); ++it) {
878 899
        _writer_bits::writeToken(*_os, it->first) << ' ';
879 900
        _writer_bits::writeToken(*_os, it->second->get());
880 901
        *_os << std::endl;
881 902
      }
882 903
    }
883 904

	
884 905
  public:
885 906

	
886 907
    /// \name Execution of the writer
887 908
    /// @{
888 909

	
889 910
    /// \brief Start the batch processing
890 911
    ///
891 912
    /// This function starts the batch processing.
892 913
    void run() {
893 914
      if (!_skip_nodes) {
894 915
        writeNodes();
895 916
      } else {
896 917
        createNodeIndex();
897 918
      }
898 919
      if (!_skip_arcs) {
899 920
        writeArcs();
900 921
      } else {
901 922
        createArcIndex();
902 923
      }
903 924
      writeAttributes();
904 925
    }
905 926

	
906 927
    /// \brief Give back the stream of the writer
907 928
    ///
908 929
    /// Give back the stream of the writer.
909 930
    std::ostream& ostream() {
910 931
      return *_os;
911 932
    }
912 933

	
913 934
    /// @}
914 935
  };
915 936

	
916
  /// \brief Return a \ref DigraphWriter class
937
  template <typename Graph>
938
  class GraphWriter;
939

	
940
  /// \brief Return a \ref GraphWriter class
917 941
  ///
918
  /// This function just returns a \ref DigraphWriter class.
919
  /// \relates DigraphWriter
920
  template <typename Digraph>
921
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
942
  /// This function just returns a \ref GraphWriter class.
943
  /// \relates GraphWriter
944
  template <typename Graph>
945
  GraphWriter<Graph> graphWriter(const Graph& graph,
922 946
                                       std::ostream& os = std::cout) {
923
    DigraphWriter<Digraph> tmp(digraph, os);
947
    GraphWriter<Graph> tmp(graph, os);
924 948
    return tmp;
925 949
  }
926 950

	
927
  /// \brief Return a \ref DigraphWriter class
951
  /// \brief Return a \ref GraphWriter class
928 952
  ///
929
  /// This function just returns a \ref DigraphWriter class.
930
  /// \relates DigraphWriter
931
  template <typename Digraph>
932
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
933
                                       const std::string& fn) {
934
    DigraphWriter<Digraph> tmp(digraph, fn);
953
  /// This function just returns a \ref GraphWriter class.
954
  /// \relates GraphWriter
955
  template <typename Graph>
956
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
957
    GraphWriter<Graph> tmp(graph, fn);
935 958
    return tmp;
936 959
  }
937 960

	
938
  /// \brief Return a \ref DigraphWriter class
961
  /// \brief Return a \ref GraphWriter class
939 962
  ///
940
  /// This function just returns a \ref DigraphWriter class.
941
  /// \relates DigraphWriter
942
  template <typename Digraph>
943
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
944
                                       const char* fn) {
945
    DigraphWriter<Digraph> tmp(digraph, fn);
963
  /// This function just returns a \ref GraphWriter class.
964
  /// \relates GraphWriter
965
  template <typename Graph>
966
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
967
    GraphWriter<Graph> tmp(graph, fn);
946 968
    return tmp;
947 969
  }
948 970

	
949
  template <typename Graph>
950
  class GraphWriter;
951

	
952
  template <typename Graph>
953
  GraphWriter<Graph> graphWriter(const Graph& graph,
954
                                 std::ostream& os = std::cout);
955

	
956
  template <typename Graph>
957
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn);
958

	
959
  template <typename Graph>
960
  GraphWriter<Graph> graphWriter(const Graph& graph, const char *fn);
961

	
962 971
  /// \ingroup lemon_io
963 972
  ///
964 973
  /// \brief \ref lgf-format "LGF" writer for directed graphs
965 974
  ///
966 975
  /// This utility writes an \ref lgf-format "LGF" file.
967 976
  ///
968 977
  /// It can be used almost the same way as \c DigraphWriter.
969 978
  /// The only difference is that this class can handle edges and
970 979
  /// edge maps as well as arcs and arc maps.
971 980
  ///
972 981
  /// The arc maps are written into the file as two columns, the
973 982
  /// caption of the columns are the name of the map prefixed with \c
974 983
  /// '+' and \c '-'. The arcs are written into the \c \@attributes
975 984
  /// section as a \c '+' or a \c '-' prefix (depends on the direction
976 985
  /// of the arc) and the label of corresponding edge.
977 986
  template <typename _Graph>
978 987
  class GraphWriter {
979 988
  public:
980 989

	
981 990
    typedef _Graph Graph;
982 991
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
983 992

	
984 993
  private:
985 994

	
986 995

	
987 996
    std::ostream* _os;
988 997
    bool local_os;
989 998

	
990 999
    const Graph& _graph;
991 1000

	
992 1001
    std::string _nodes_caption;
993 1002
    std::string _edges_caption;
994 1003
    std::string _attributes_caption;
995 1004

	
996 1005
    typedef std::map<Node, std::string> NodeIndex;
997 1006
    NodeIndex _node_index;
998 1007
    typedef std::map<Edge, std::string> EdgeIndex;
999 1008
    EdgeIndex _edge_index;
1000 1009

	
1001 1010
    typedef std::vector<std::pair<std::string,
1002 1011
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
1003 1012
    NodeMaps _node_maps;
1004 1013

	
1005 1014
    typedef std::vector<std::pair<std::string,
1006 1015
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
1007 1016
    EdgeMaps _edge_maps;
1008 1017

	
1009 1018
    typedef std::vector<std::pair<std::string,
... ...
@@ -1481,127 +1490,96 @@
1481 1490

	
1482 1491
    void writeAttributes() {
1483 1492
      if (_attributes.empty()) return;
1484 1493
      *_os << "@attributes";
1485 1494
      if (!_attributes_caption.empty()) {
1486 1495
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1487 1496
      }
1488 1497
      *_os << std::endl;
1489 1498
      for (typename Attributes::iterator it = _attributes.begin();
1490 1499
           it != _attributes.end(); ++it) {
1491 1500
        _writer_bits::writeToken(*_os, it->first) << ' ';
1492 1501
        _writer_bits::writeToken(*_os, it->second->get());
1493 1502
        *_os << std::endl;
1494 1503
      }
1495 1504
    }
1496 1505

	
1497 1506
  public:
1498 1507

	
1499 1508
    /// \name Execution of the writer
1500 1509
    /// @{
1501 1510

	
1502 1511
    /// \brief Start the batch processing
1503 1512
    ///
1504 1513
    /// This function starts the batch processing.
1505 1514
    void run() {
1506 1515
      if (!_skip_nodes) {
1507 1516
        writeNodes();
1508 1517
      } else {
1509 1518
        createNodeIndex();
1510 1519
      }
1511 1520
      if (!_skip_edges) {
1512 1521
        writeEdges();
1513 1522
      } else {
1514 1523
        createEdgeIndex();
1515 1524
      }
1516 1525
      writeAttributes();
1517 1526
    }
1518 1527

	
1519 1528
    /// \brief Give back the stream of the writer
1520 1529
    ///
1521 1530
    /// Give back the stream of the writer
1522 1531
    std::ostream& ostream() {
1523 1532
      return *_os;
1524 1533
    }
1525 1534

	
1526 1535
    /// @}
1527 1536
  };
1528 1537

	
1529
  /// \brief Return a \ref GraphWriter class
1530
  ///
1531
  /// This function just returns a \ref GraphWriter class.
1532
  /// \relates GraphWriter
1533
  template <typename Graph>
1534
  GraphWriter<Graph> graphWriter(const Graph& graph,
1535
                                 std::ostream& os = std::cout) {
1536
    GraphWriter<Graph> tmp(graph, os);
1537
    return tmp;
1538
  }
1539

	
1540
  /// \brief Return a \ref GraphWriter class
1541
  ///
1542
  /// This function just returns a \ref GraphWriter class.
1543
  /// \relates GraphWriter
1544
  template <typename Graph>
1545
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
1546
    GraphWriter<Graph> tmp(graph, fn);
1547
    return tmp;
1548
  }
1549

	
1550
  /// \brief Return a \ref GraphWriter class
1551
  ///
1552
  /// This function just returns a \ref GraphWriter class.
1553
  /// \relates GraphWriter
1554
  template <typename Graph>
1555
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
1556
    GraphWriter<Graph> tmp(graph, fn);
1557
    return tmp;
1558
  }
1559

	
1560 1538
  class SectionWriter;
1561 1539

	
1562 1540
  SectionWriter sectionWriter(std::istream& is);
1563 1541
  SectionWriter sectionWriter(const std::string& fn);
1564 1542
  SectionWriter sectionWriter(const char* fn);
1565 1543

	
1566 1544
  /// \ingroup lemon_io
1567 1545
  ///
1568 1546
  /// \brief Section writer class
1569 1547
  ///
1570 1548
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
1571 1549
  /// which contain any data in arbitrary format. Such sections can be
1572 1550
  /// written with this class. A writing rule can be added to the
1573 1551
  /// class with two different functions. With the \c sectionLines()
1574 1552
  /// function a generator can write the section line-by-line, while
1575 1553
  /// with the \c sectionStream() member the section can be written to
1576 1554
  /// an output stream.
1577 1555
  class SectionWriter {
1578 1556
  private:
1579 1557

	
1580 1558
    std::ostream* _os;
1581 1559
    bool local_os;
1582 1560

	
1583 1561
    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
1584 1562
    Sections;
1585 1563

	
1586 1564
    Sections _sections;
1587 1565

	
1588 1566
  public:
1589 1567

	
1590 1568
    /// \brief Constructor
1591 1569
    ///
1592 1570
    /// Construct a section writer, which writes to the given output
1593 1571
    /// stream.
1594 1572
    SectionWriter(std::ostream& os)
1595 1573
      : _os(&os), local_os(false) {}
1596 1574

	
1597 1575
    /// \brief Constructor
1598 1576
    ///
1599 1577
    /// Construct a section writer, which writes into the given file.
1600 1578
    SectionWriter(const std::string& fn)
1601 1579
      : _os(new std::ofstream(fn.c_str())), local_os(true) {
1602 1580
      if (!(*_os)) {
1603 1581
        delete _os;
1604 1582
        throw IoError("Cannot write file", fn);
1605 1583
      }
1606 1584
    }
1607 1585

	
0 comments (0 inline)