gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Move to private copy constrcutors
0 2 0
default
2 files changed with 201 insertions and 148 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -365,48 +365,60 @@
365 365
    public:
366 366
      
367 367
      StreamSection(const Functor& functor) : _functor(functor) {}
368 368
      virtual ~StreamSection() {} 
369 369

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

	
389
  template <typename Digraph>
390
  class DigraphReader;
391

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

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

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

	
389 401
  /// \ingroup lemon_io
390 402
  ///  
391 403
  /// \brief LGF reader for directed graphs
392 404
  ///
393 405
  /// This utility reads an \ref lgf-format "LGF" file.
394 406
  ///
395 407
  /// The reading method does a batch processing. The user creates a
396 408
  /// reader object, then various reading rules can be added to the
397 409
  /// reader, and eventually the reading is executed with the \c run()
398 410
  /// member function. A map reading rule can be added to the reader
399 411
  /// with the \c nodeMap() or \c arcMap() members. An optional
400 412
  /// converter parameter can also be added as a standard functor
401 413
  /// converting from std::string to the value type of the map. If it
402 414
  /// is set, it will determine how the tokens in the file should be
403 415
  /// is converted to the map's value type. If the functor is not set,
404 416
  /// then a default conversion will be used. One map can be read into
405 417
  /// multiple map objects at the same time. The \c attribute(), \c
406 418
  /// node() and \c arc() functions are used to add attribute reading
407 419
  /// rules.
408 420
  ///
409 421
  ///\code
410 422
  ///     DigraphReader<Digraph>(std::cin, digraph).
411 423
  ///       nodeMap("coordinates", coord_map).
412 424
  ///       arcMap("capacity", cap_map).
... ...
@@ -488,98 +500,101 @@
488 500
    /// input stream.
489 501
    DigraphReader(std::istream& is, Digraph& digraph) 
490 502
      : _is(&is), local_is(false), _digraph(digraph),
491 503
	_use_nodes(false), _use_arcs(false),
492 504
	_skip_nodes(false), _skip_arcs(false) {}
493 505

	
494 506
    /// \brief Constructor
495 507
    ///
496 508
    /// Construct a directed graph reader, which reads from the given
497 509
    /// file.
498 510
    DigraphReader(const std::string& fn, Digraph& digraph) 
499 511
      : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
500 512
    	_use_nodes(false), _use_arcs(false),
501 513
	_skip_nodes(false), _skip_arcs(false) {}
502 514
    
503 515
    /// \brief Constructor
504 516
    ///
505 517
    /// Construct a directed graph reader, which reads from the given
506 518
    /// file.
507 519
    DigraphReader(const char* fn, Digraph& digraph) 
508 520
      : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
509 521
    	_use_nodes(false), _use_arcs(false),
510 522
	_skip_nodes(false), _skip_arcs(false) {}
511 523

	
512
    /// \brief Copy constructor
513
    ///
514
    /// The copy constructor transfers all data from the other reader,
515
    /// therefore the copied reader will not be usable more. 
516
    DigraphReader(DigraphReader& other) 
517
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
518
	_use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
519
	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
520

	
521
      other._is = 0;
522
      other.local_is = false;
523
      
524
      _node_index.swap(other._node_index);
525
      _arc_index.swap(other._arc_index);
526

	
527
      _node_maps.swap(other._node_maps);
528
      _arc_maps.swap(other._arc_maps);
529
      _attributes.swap(other._attributes);
530

	
531
      _nodes_caption = other._nodes_caption;
532
      _arcs_caption = other._arcs_caption;
533
      _attributes_caption = other._attributes_caption;
534

	
535
    }
536

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

	
544 531
      for (typename ArcMaps::iterator it = _arc_maps.begin(); 
545 532
	   it != _arc_maps.end(); ++it) {
546 533
	delete it->second;
547 534
      }
548 535

	
549 536
      for (typename Attributes::iterator it = _attributes.begin(); 
550 537
	   it != _attributes.end(); ++it) {
551 538
	delete it->second;
552 539
      }
553 540

	
554 541
      if (local_is) {
555 542
	delete _is;
556 543
      }
557 544

	
558 545
    }
559 546

	
560 547
  private:
561
    
548

	
549
    friend DigraphReader<Digraph> digraphReader<>(std::istream& is, 
550
						  Digraph& digraph);    
551
    friend DigraphReader<Digraph> digraphReader<>(const std::string& fn, 
552
						  Digraph& digraph);   
553
    friend DigraphReader<Digraph> digraphReader<>(const char *fn, 
554
						  Digraph& digraph);    
555

	
556
    DigraphReader(DigraphReader& other) 
557
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
558
	_use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
559
	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
560

	
561
      other._is = 0;
562
      other.local_is = false;
563
      
564
      _node_index.swap(other._node_index);
565
      _arc_index.swap(other._arc_index);
566

	
567
      _node_maps.swap(other._node_maps);
568
      _arc_maps.swap(other._arc_maps);
569
      _attributes.swap(other._attributes);
570

	
571
      _nodes_caption = other._nodes_caption;
572
      _arcs_caption = other._arcs_caption;
573
      _attributes_caption = other._attributes_caption;
574

	
575
    }
576

	
562 577
    DigraphReader& operator=(const DigraphReader&);
563 578

	
564 579
  public:
565 580

	
566 581
    /// \name Reading rules
567 582
    /// @{
568 583
    
569 584
    /// \brief Node map reading rule
570 585
    ///
571 586
    /// Add a node map reading rule to the reader.
572 587
    template <typename Map>
573 588
    DigraphReader& nodeMap(const std::string& caption, Map& map) {
574 589
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
575 590
      _reader_bits::MapStorageBase<Node>* storage = 
576 591
	new _reader_bits::MapStorage<Node, Map>(map);
577 592
      _node_maps.push_back(std::make_pair(caption, storage));
578 593
      return *this;
579 594
    }
580 595

	
581 596
    /// \brief Node map reading rule
582 597
    ///
583 598
    /// Add a node map reading rule with specialized converter to the
584 599
    /// reader.
585 600
    template <typename Map, typename Converter>
... ...
@@ -1161,48 +1176,60 @@
1161 1176
  };
1162 1177

	
1163 1178
  /// \relates DigraphReader
1164 1179
  template <typename Digraph>
1165 1180
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
1166 1181
    DigraphReader<Digraph> tmp(is, digraph);
1167 1182
    return tmp;
1168 1183
  }
1169 1184

	
1170 1185
  /// \relates DigraphReader
1171 1186
  template <typename Digraph>
1172 1187
  DigraphReader<Digraph> digraphReader(const std::string& fn, 
1173 1188
				       Digraph& digraph) {
1174 1189
    DigraphReader<Digraph> tmp(fn, digraph);
1175 1190
    return tmp;
1176 1191
  }
1177 1192

	
1178 1193
  /// \relates DigraphReader
1179 1194
  template <typename Digraph>
1180 1195
  DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
1181 1196
    DigraphReader<Digraph> tmp(fn, digraph);
1182 1197
    return tmp;
1183 1198
  }
1184 1199

	
1200
  template <typename Graph>
1201
  class GraphReader;
1202

	
1203
  template <typename Graph>
1204
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph);    
1205

	
1206
  template <typename Graph>
1207
  GraphReader<Graph> graphReader(const std::string& fn, Graph& graph);   
1208

	
1209
  template <typename Graph>
1210
  GraphReader<Graph> graphReader(const char *fn, Graph& graph);    
1211

	
1185 1212
  /// \ingroup lemon_io
1186 1213
  ///  
1187 1214
  /// \brief LGF reader for undirected graphs
1188 1215
  ///
1189 1216
  /// This utility reads an \ref lgf-format "LGF" file.
1190 1217
  template <typename _Graph>
1191 1218
  class GraphReader {
1192 1219
  public:
1193 1220

	
1194 1221
    typedef _Graph Graph;
1195 1222
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1196 1223
    
1197 1224
  private:
1198 1225

	
1199 1226
    std::istream* _is;
1200 1227
    bool local_is;
1201 1228

	
1202 1229
    Graph& _graph;
1203 1230

	
1204 1231
    std::string _nodes_caption;
1205 1232
    std::string _edges_caption;
1206 1233
    std::string _attributes_caption;
1207 1234

	
1208 1235
    typedef std::map<std::string, Node> NodeIndex;
... ...
@@ -1239,98 +1266,98 @@
1239 1266
    /// input stream.
1240 1267
    GraphReader(std::istream& is, Graph& graph) 
1241 1268
      : _is(&is), local_is(false), _graph(graph),
1242 1269
	_use_nodes(false), _use_edges(false),
1243 1270
	_skip_nodes(false), _skip_edges(false) {}
1244 1271

	
1245 1272
    /// \brief Constructor
1246 1273
    ///
1247 1274
    /// Construct a undirected graph reader, which reads from the given
1248 1275
    /// file.
1249 1276
    GraphReader(const std::string& fn, Graph& graph) 
1250 1277
      : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph),
1251 1278
    	_use_nodes(false), _use_edges(false),
1252 1279
	_skip_nodes(false), _skip_edges(false) {}
1253 1280
    
1254 1281
    /// \brief Constructor
1255 1282
    ///
1256 1283
    /// Construct a undirected graph reader, which reads from the given
1257 1284
    /// file.
1258 1285
    GraphReader(const char* fn, Graph& graph) 
1259 1286
      : _is(new std::ifstream(fn)), local_is(true), _graph(graph),
1260 1287
    	_use_nodes(false), _use_edges(false),
1261 1288
	_skip_nodes(false), _skip_edges(false) {}
1262 1289

	
1263
    /// \brief Copy constructor
1264
    ///
1265
    /// The copy constructor transfers all data from the other reader,
1266
    /// therefore the copied reader will not be usable more. 
1267
    GraphReader(GraphReader& other) 
1268
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1269
	_use_nodes(other._use_nodes), _use_edges(other._use_edges),
1270
	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1271

	
1272
      other._is = 0;
1273
      other.local_is = false;
1274
      
1275
      _node_index.swap(other._node_index);
1276
      _edge_index.swap(other._edge_index);
1277

	
1278
      _node_maps.swap(other._node_maps);
1279
      _edge_maps.swap(other._edge_maps);
1280
      _attributes.swap(other._attributes);
1281

	
1282
      _nodes_caption = other._nodes_caption;
1283
      _edges_caption = other._edges_caption;
1284
      _attributes_caption = other._attributes_caption;
1285

	
1286
    }
1287

	
1288 1290
    /// \brief Destructor
1289 1291
    ~GraphReader() {
1290 1292
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
1291 1293
	   it != _node_maps.end(); ++it) {
1292 1294
	delete it->second;
1293 1295
      }
1294 1296

	
1295 1297
      for (typename EdgeMaps::iterator it = _edge_maps.begin(); 
1296 1298
	   it != _edge_maps.end(); ++it) {
1297 1299
	delete it->second;
1298 1300
      }
1299 1301

	
1300 1302
      for (typename Attributes::iterator it = _attributes.begin(); 
1301 1303
	   it != _attributes.end(); ++it) {
1302 1304
	delete it->second;
1303 1305
      }
1304 1306

	
1305 1307
      if (local_is) {
1306 1308
	delete _is;
1307 1309
      }
1308 1310

	
1309 1311
    }
1310 1312

	
1311 1313
  private:
1312
    
1314
    friend GraphReader<Graph> graphReader<>(std::istream& is, Graph& graph);    
1315
    friend GraphReader<Graph> graphReader<>(const std::string& fn, 
1316
					    Graph& graph);   
1317
    friend GraphReader<Graph> graphReader<>(const char *fn, Graph& graph);    
1318

	
1319
    GraphReader(GraphReader& other) 
1320
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1321
	_use_nodes(other._use_nodes), _use_edges(other._use_edges),
1322
	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1323

	
1324
      other._is = 0;
1325
      other.local_is = false;
1326
      
1327
      _node_index.swap(other._node_index);
1328
      _edge_index.swap(other._edge_index);
1329

	
1330
      _node_maps.swap(other._node_maps);
1331
      _edge_maps.swap(other._edge_maps);
1332
      _attributes.swap(other._attributes);
1333

	
1334
      _nodes_caption = other._nodes_caption;
1335
      _edges_caption = other._edges_caption;
1336
      _attributes_caption = other._attributes_caption;
1337

	
1338
    }
1339

	
1313 1340
    GraphReader& operator=(const GraphReader&);
1314 1341

	
1315 1342
  public:
1316 1343

	
1317 1344
    /// \name Reading rules
1318 1345
    /// @{
1319 1346
    
1320 1347
    /// \brief Node map reading rule
1321 1348
    ///
1322 1349
    /// Add a node map reading rule to the reader.
1323 1350
    template <typename Map>
1324 1351
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1325 1352
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1326 1353
      _reader_bits::MapStorageBase<Node>* storage = 
1327 1354
	new _reader_bits::MapStorage<Node, Map>(map);
1328 1355
      _node_maps.push_back(std::make_pair(caption, storage));
1329 1356
      return *this;
1330 1357
    }
1331 1358

	
1332 1359
    /// \brief Node map reading rule
1333 1360
    ///
1334 1361
    /// Add a node map reading rule with specialized converter to the
1335 1362
    /// reader.
1336 1363
    template <typename Map, typename Converter>
... ...
@@ -1956,117 +1983,123 @@
1956 1983
  };
1957 1984

	
1958 1985
  /// \relates GraphReader
1959 1986
  template <typename Graph>
1960 1987
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph) {
1961 1988
    GraphReader<Graph> tmp(is, graph);
1962 1989
    return tmp;
1963 1990
  }
1964 1991

	
1965 1992
  /// \relates GraphReader
1966 1993
  template <typename Graph>
1967 1994
  GraphReader<Graph> graphReader(const std::string& fn, 
1968 1995
				       Graph& graph) {
1969 1996
    GraphReader<Graph> tmp(fn, graph);
1970 1997
    return tmp;
1971 1998
  }
1972 1999

	
1973 2000
  /// \relates GraphReader
1974 2001
  template <typename Graph>
1975 2002
  GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
1976 2003
    GraphReader<Graph> tmp(fn, graph);
1977 2004
    return tmp;
1978 2005
  }
1979 2006

	
2007
  class SectionReader;
2008

	
2009
  SectionReader sectionReader(std::istream& is);
2010
  SectionReader sectionReader(const std::string& fn);
2011
  SectionReader sectionReader(const char* fn);
2012
  
1980 2013
  /// \brief Section reader class
1981 2014
  ///
1982 2015
  /// In the \e LGF file extra sections can be placed, which contain
1983 2016
  /// any data in arbitrary format. Such sections can be read with
1984 2017
  /// this class. A reading rule can be added with two different
1985 2018
  /// functions, with the \c sectionLines() function a functor can
1986 2019
  /// process the section line-by-line. While with the \c
1987 2020
  /// sectionStream() member the section can be read from an input
1988 2021
  /// stream.
1989 2022
  class SectionReader {
1990 2023
  private:
1991 2024
    
1992 2025
    std::istream* _is;
1993 2026
    bool local_is;
1994 2027

	
1995 2028
    typedef std::map<std::string, _reader_bits::Section*> Sections;
1996 2029
    Sections _sections;
1997 2030

	
1998 2031
    int line_num;
1999 2032
    std::istringstream line;
2000 2033

	
2001 2034
  public:
2002 2035

	
2003 2036
    /// \brief Constructor
2004 2037
    ///
2005 2038
    /// Construct a section reader, which reads from the given input
2006 2039
    /// stream.
2007 2040
    SectionReader(std::istream& is) 
2008 2041
      : _is(&is), local_is(false) {}
2009 2042

	
2010 2043
    /// \brief Constructor
2011 2044
    ///
2012 2045
    /// Construct a section reader, which reads from the given file.
2013 2046
    SectionReader(const std::string& fn) 
2014 2047
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2015 2048
    
2016 2049
    /// \brief Constructor
2017 2050
    ///
2018 2051
    /// Construct a section reader, which reads from the given file.
2019 2052
    SectionReader(const char* fn) 
2020 2053
      : _is(new std::ifstream(fn)), local_is(true) {}
2021 2054

	
2022
    /// \brief Copy constructor
2023
    ///
2024
    /// The copy constructor transfers all data from the other reader,
2025
    /// therefore the copied reader will not be usable more. 
2026
    SectionReader(SectionReader& other) 
2027
      : _is(other._is), local_is(other.local_is) {
2028

	
2029
      other._is = 0;
2030
      other.local_is = false;
2031
      
2032
      _sections.swap(other._sections);
2033
    }
2034

	
2035 2055
    /// \brief Destructor
2036 2056
    ~SectionReader() {
2037 2057
      for (Sections::iterator it = _sections.begin(); 
2038 2058
	   it != _sections.end(); ++it) {
2039 2059
	delete it->second;
2040 2060
      }
2041 2061

	
2042 2062
      if (local_is) {
2043 2063
	delete _is;
2044 2064
      }
2045 2065

	
2046 2066
    }
2047 2067

	
2048 2068
  private:
2069

	
2070
    friend SectionReader sectionReader(std::istream& is);
2071
    friend SectionReader sectionReader(const std::string& fn);
2072
    friend SectionReader sectionReader(const char* fn);
2073

	
2074
    SectionReader(SectionReader& other) 
2075
      : _is(other._is), local_is(other.local_is) {
2076

	
2077
      other._is = 0;
2078
      other.local_is = false;
2079
      
2080
      _sections.swap(other._sections);
2081
    }
2049 2082
    
2050 2083
    SectionReader& operator=(const SectionReader&);
2051 2084

	
2052 2085
  public:
2053 2086

	
2054 2087
    /// \name Section readers
2055 2088
    /// @{
2056 2089

	
2057 2090
    /// \brief Add a section processor with line oriented reading
2058 2091
    ///
2059 2092
    /// The first parameter is the type descriptor of the section, the
2060 2093
    /// second is a functor, which takes just one \c std::string
2061 2094
    /// parameter. At the reading process, each line of the section
2062 2095
    /// will be given to the functor object. However, the empty lines
2063 2096
    /// and the comment lines are filtered out, and the leading
2064 2097
    /// whitespaces are trimmed from each processed string.
2065 2098
    ///
2066 2099
    /// For example let's see a section, which contain several
2067 2100
    /// integers, which should be inserted into a vector.
2068 2101
    ///\code
2069 2102
    ///  @numbers
2070 2103
    ///  12 45 23
2071 2104
    ///  4
2072 2105
    ///  23 6
... ...
@@ -2274,76 +2307,61 @@
2274 2307
    std::istringstream line;
2275 2308
    
2276 2309
  public:
2277 2310

	
2278 2311
    /// \brief Constructor
2279 2312
    ///
2280 2313
    /// Construct an \e LGF contents reader, which reads from the given
2281 2314
    /// input stream.
2282 2315
    LgfContents(std::istream& is) 
2283 2316
      : _is(&is), local_is(false) {}
2284 2317

	
2285 2318
    /// \brief Constructor
2286 2319
    ///
2287 2320
    /// Construct an \e LGF contents reader, which reads from the given
2288 2321
    /// file.
2289 2322
    LgfContents(const std::string& fn) 
2290 2323
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2291 2324

	
2292 2325
    /// \brief Constructor
2293 2326
    ///
2294 2327
    /// Construct an \e LGF contents reader, which reads from the given
2295 2328
    /// file.
2296 2329
    LgfContents(const char* fn)
2297 2330
      : _is(new std::ifstream(fn)), local_is(true) {}
2298

	
2299
    /// \brief Copy constructor
2300
    ///
2301
    /// The copy constructor transfers all data from the other reader,
2302
    /// therefore the copied reader will not be usable more. 
2303
    LgfContents(LgfContents& other)
2304
      : _is(other._is), local_is(other.local_is) {
2305
      
2306
      other._is = 0;
2307
      other.local_is = false;
2308
      
2309
      _node_sections.swap(other._node_sections);
2310
      _edge_sections.swap(other._edge_sections);
2311
      _attribute_sections.swap(other._attribute_sections);
2312
      _extra_sections.swap(other._extra_sections);
2313

	
2314
      _arc_sections.swap(other._arc_sections);
2315

	
2316
      _node_maps.swap(other._node_maps);
2317
      _edge_maps.swap(other._edge_maps);
2318
      _attributes.swap(other._attributes);
2319
    }
2320 2331
    
2321 2332
    /// \brief Destructor
2322 2333
    ~LgfContents() {
2323 2334
      if (local_is) delete _is;
2324 2335
    }
2325 2336

	
2337
  private:
2338
    
2339
    LgfContents(const LgfContents&);
2340
    LgfContents& operator=(const LgfContents&);
2341

	
2342
  public:
2343

	
2326 2344

	
2327 2345
    /// \name Node sections
2328 2346
    /// @{
2329 2347

	
2330 2348
    /// \brief Gives back the number of node sections in the file.
2331 2349
    ///
2332 2350
    /// Gives back the number of node sections in the file.
2333 2351
    int nodeSectionNum() const {
2334 2352
      return _node_sections.size();
2335 2353
    }
2336 2354

	
2337 2355
    /// \brief Returns the section name at the given position. 
2338 2356
    ///
2339 2357
    /// Returns the section name at the given position. 
2340 2358
    const std::string& nodeSection(int i) const {
2341 2359
      return _node_sections[i];
2342 2360
    }
2343 2361

	
2344 2362
    /// \brief Gives back the node maps for the given section.
2345 2363
    ///
2346 2364
    /// Gives back the node maps for the given section.
2347 2365
    const std::vector<std::string>& nodeMapNames(int i) const {
2348 2366
      return _node_maps[i];
2349 2367
    }
Ignore white space 48 line context
... ...
@@ -283,48 +283,63 @@
283 283
      while (is.get(c)) {
284 284
	if (isWhiteSpace(c) || isEscaped(c)) {
285 285
	  return true;
286 286
	}
287 287
      }
288 288
      return false;
289 289
    }
290 290
    
291 291
    std::ostream& writeToken(std::ostream& os, const std::string& str) {
292 292

	
293 293
      if (requireEscape(str)) {
294 294
	os << '\"';
295 295
	for (std::string::const_iterator it = str.begin(); 
296 296
	     it != str.end(); ++it) {
297 297
	  writeEscape(os, *it);
298 298
	}	
299 299
	os << '\"';
300 300
      } else {
301 301
	os << str;
302 302
      }
303 303
      return os;
304 304
    }
305 305

	
306 306
  }
307

	
308
  template <typename Digraph>
309
  class DigraphWriter;
310

	
311
  template <typename Digraph>
312
  DigraphWriter<Digraph> digraphWriter(std::ostream& os, 
313
				       const Digraph& digraph);
314

	
315
  template <typename Digraph>
316
  DigraphWriter<Digraph> digraphWriter(const std::string& fn, 
317
				       const Digraph& digraph);
318

	
319
  template <typename Digraph>
320
  DigraphWriter<Digraph> digraphWriter(const char *fn, 
321
				       const Digraph& digraph);
307 322
  
308 323
  /// \ingroup lemon_io
309 324
  ///  
310 325
  /// \brief LGF writer for directed graphs
311 326
  ///
312 327
  /// This utility writes an \ref lgf-format "LGF" file.
313 328
  ///
314 329
  /// The writing method does a batch processing. The user creates a
315 330
  /// writer object, then various writing rules can be added to the
316 331
  /// writer, and eventually the writing is executed with the \c run()
317 332
  /// member function. A map writing rule can be added to the writer
318 333
  /// with the \c nodeMap() or \c arcMap() members. An optional
319 334
  /// converter parameter can also be added as a standard functor
320 335
  /// converting from the value type of the map to std::string. If it
321 336
  /// is set, it will determine how the map's value type is written to
322 337
  /// the output stream. If the functor is not set, then a default
323 338
  /// conversion will be used. The \c attribute(), \c node() and \c
324 339
  /// arc() functions are used to add attribute writing rules.
325 340
  ///
326 341
  ///\code
327 342
  ///     DigraphWriter<Digraph>(std::cout, digraph).
328 343
  ///       nodeMap("coordinates", coord_map).
329 344
  ///       nodeMap("size", size).
330 345
  ///       nodeMap("title", title).
... ...
@@ -341,146 +356,149 @@
341 356
  /// the \c nodes(), \c arcs() or \c
342 357
  /// attributes() functions.
343 358
  ///
344 359
  /// The \c skipNodes() and \c skipArcs() functions forbid the
345 360
  /// writing of the sections. If two arc sections should be written
346 361
  /// to the output, it can be done in two passes, the first pass
347 362
  /// writes the node section and the first arc section, then the
348 363
  /// second pass skips the node section and writes just the arc
349 364
  /// section to the stream. The output stream can be retrieved with
350 365
  /// the \c ostream() function, hence the second pass can append its
351 366
  /// output to the output of the first pass.
352 367
  template <typename _Digraph>
353 368
  class DigraphWriter {
354 369
  public:
355 370

	
356 371
    typedef _Digraph Digraph;
357 372
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
358 373
    
359 374
  private:
360 375

	
361 376

	
362 377
    std::ostream* _os;
363 378
    bool local_os;
364 379

	
365
    Digraph& _digraph;
380
    const Digraph& _digraph;
366 381

	
367 382
    std::string _nodes_caption;
368 383
    std::string _arcs_caption;
369 384
    std::string _attributes_caption;
370 385
    
371 386
    typedef std::map<Node, std::string> NodeIndex;
372 387
    NodeIndex _node_index;
373 388
    typedef std::map<Arc, std::string> ArcIndex;
374 389
    ArcIndex _arc_index;
375 390

	
376 391
    typedef std::vector<std::pair<std::string, 
377 392
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;    
378 393
    NodeMaps _node_maps; 
379 394

	
380 395
    typedef std::vector<std::pair<std::string, 
381 396
      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
382 397
    ArcMaps _arc_maps;
383 398

	
384 399
    typedef std::vector<std::pair<std::string, 
385 400
      _writer_bits::ValueStorageBase*> > Attributes;
386 401
    Attributes _attributes;
387 402

	
388 403
    bool _skip_nodes;
389 404
    bool _skip_arcs;
390 405

	
391 406
  public:
392 407

	
393 408
    /// \brief Constructor
394 409
    ///
395 410
    /// Construct a directed graph writer, which writes to the given
396 411
    /// output stream.
397
    DigraphWriter(std::ostream& is, Digraph& digraph) 
412
    DigraphWriter(std::ostream& is, const Digraph& digraph) 
398 413
      : _os(&is), local_os(false), _digraph(digraph),
399 414
	_skip_nodes(false), _skip_arcs(false) {}
400 415

	
401 416
    /// \brief Constructor
402 417
    ///
403 418
    /// Construct a directed graph writer, which writes to the given
404 419
    /// output file.
405
    DigraphWriter(const std::string& fn, Digraph& digraph) 
420
    DigraphWriter(const std::string& fn, const Digraph& digraph) 
406 421
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
407 422
	_skip_nodes(false), _skip_arcs(false) {}
408 423

	
409 424
    /// \brief Constructor
410 425
    ///
411 426
    /// Construct a directed graph writer, which writes to the given
412 427
    /// output file.
413
    DigraphWriter(const char* fn, Digraph& digraph) 
428
    DigraphWriter(const char* fn, const Digraph& digraph) 
414 429
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
415 430
	_skip_nodes(false), _skip_arcs(false) {}
416 431

	
417
    /// \brief Copy constructor
418
    ///
419
    /// The copy constructor transfers all data from the other writer,
420
    /// therefore the copied writer will not be usable more. 
421
    DigraphWriter(DigraphWriter& other) 
422
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
423
	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
424

	
425
      other._os = 0;
426
      other.local_os = false;
427

	
428
      _node_index.swap(other._node_index);
429
      _arc_index.swap(other._arc_index);
430

	
431
      _node_maps.swap(other._node_maps);
432
      _arc_maps.swap(other._arc_maps);
433
      _attributes.swap(other._attributes);
434

	
435
      _nodes_caption = other._nodes_caption;
436
      _arcs_caption = other._arcs_caption;
437
      _attributes_caption = other._attributes_caption;
438
    }
439

	
440 432
    /// \brief Destructor
441 433
    ~DigraphWriter() {
442 434
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
443 435
	   it != _node_maps.end(); ++it) {
444 436
	delete it->second;
445 437
      }
446 438

	
447 439
      for (typename ArcMaps::iterator it = _arc_maps.begin(); 
448 440
	   it != _arc_maps.end(); ++it) {
449 441
	delete it->second;
450 442
      }
451 443

	
452 444
      for (typename Attributes::iterator it = _attributes.begin(); 
453 445
	   it != _attributes.end(); ++it) {
454 446
	delete it->second;
455 447
      }
456 448

	
457 449
      if (local_os) {
458 450
	delete _os;
459 451
      }
460 452
    }
461 453

	
462 454
  private:
455

	
456
    friend DigraphWriter<Digraph> digraphWriter<>(std::ostream& os, 
457
						  const Digraph& digraph);
458
    friend DigraphWriter<Digraph> digraphWriter<>(const std::string& fn, 
459
						  const Digraph& digraph);   
460
    friend DigraphWriter<Digraph> digraphWriter<>(const char *fn, 
461
						  const Digraph& digraph);
462

	
463
    DigraphWriter(DigraphWriter& other) 
464
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
465
	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
466

	
467
      other._os = 0;
468
      other.local_os = false;
469

	
470
      _node_index.swap(other._node_index);
471
      _arc_index.swap(other._arc_index);
472

	
473
      _node_maps.swap(other._node_maps);
474
      _arc_maps.swap(other._arc_maps);
475
      _attributes.swap(other._attributes);
476

	
477
      _nodes_caption = other._nodes_caption;
478
      _arcs_caption = other._arcs_caption;
479
      _attributes_caption = other._attributes_caption;
480
    }
463 481
    
464 482
    DigraphWriter& operator=(const DigraphWriter&);
465 483

	
466 484
  public:
467 485

	
468 486
    /// \name Writing rules
469 487
    /// @{
470 488
    
471 489
    /// \brief Node map reading rule
472 490
    ///
473 491
    /// Add a node map reading rule to the writer.
474 492
    template <typename Map>
475 493
    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
476 494
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
477 495
      _writer_bits::MapStorageBase<Node>* storage = 
478 496
	new _writer_bits::MapStorage<Node, Map>(map);
479 497
      _node_maps.push_back(std::make_pair(caption, storage));
480 498
      return *this;
481 499
    }
482 500

	
483 501
    /// \brief Node map writing rule
484 502
    ///
485 503
    /// Add a node map writing rule with specialized converter to the
486 504
    /// writer.
... ...
@@ -823,68 +841,82 @@
823 841
	writeNodes();
824 842
      } else {
825 843
	createNodeIndex();
826 844
      }
827 845
      if (!_skip_arcs) {      
828 846
	writeArcs();
829 847
      } else {
830 848
	createArcIndex();
831 849
      }
832 850
      writeAttributes();
833 851
    }
834 852

	
835 853
    /// \brief Gives back the stream of the writer
836 854
    ///
837 855
    /// Gives back the stream of the writer
838 856
    std::ostream& ostream() {
839 857
      return *_os;
840 858
    }
841 859

	
842 860
    /// @}
843 861
  };
844 862

	
845 863
  /// \relates DigraphWriter
846 864
  template <typename Digraph>
847
  DigraphWriter<Digraph> digraphWriter(std::ostream& os, Digraph& digraph) {
865
  DigraphWriter<Digraph> digraphWriter(std::ostream& os, 
866
				       const Digraph& digraph) {
848 867
    DigraphWriter<Digraph> tmp(os, digraph);
849 868
    return tmp;
850 869
  }
851 870

	
852 871
  /// \relates DigraphWriter
853 872
  template <typename Digraph>
854 873
  DigraphWriter<Digraph> digraphWriter(const std::string& fn, 
855
				       Digraph& digraph) {
874
				       const Digraph& digraph) {
856 875
    DigraphWriter<Digraph> tmp(fn, digraph);
857 876
    return tmp;
858 877
  }
859 878

	
860 879
  /// \relates DigraphWriter
861 880
  template <typename Digraph>
862
  DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) {
881
  DigraphWriter<Digraph> digraphWriter(const char* fn, 
882
				       const Digraph& digraph) {
863 883
    DigraphWriter<Digraph> tmp(fn, digraph);
864 884
    return tmp;
865 885
  }
866 886

	
887
  template <typename Graph>
888
  class GraphWriter;
889

	
890
  template <typename Graph>
891
  GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph);    
892

	
893
  template <typename Graph>
894
  GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph);   
895

	
896
  template <typename Graph>
897
  GraphWriter<Graph> graphWriter(const char *fn, const Graph& graph);    
898

	
867 899
  /// \ingroup lemon_io
868 900
  ///  
869 901
  /// \brief LGF writer for directed graphs
870 902
  ///
871 903
  /// This utility writes an \ref lgf-format "LGF" file.
872 904
  template <typename _Graph>
873 905
  class GraphWriter {
874 906
  public:
875 907

	
876 908
    typedef _Graph Graph;
877 909
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
878 910
    
879 911
  private:
880 912

	
881 913

	
882 914
    std::ostream* _os;
883 915
    bool local_os;
884 916

	
885 917
    Graph& _graph;
886 918

	
887 919
    std::string _nodes_caption;
888 920
    std::string _edges_caption;
889 921
    std::string _attributes_caption;
890 922
    
... ...
@@ -893,115 +925,118 @@
893 925
    typedef std::map<Edge, std::string> EdgeIndex;
894 926
    EdgeIndex _edge_index;
895 927

	
896 928
    typedef std::vector<std::pair<std::string, 
897 929
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;    
898 930
    NodeMaps _node_maps; 
899 931

	
900 932
    typedef std::vector<std::pair<std::string, 
901 933
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
902 934
    EdgeMaps _edge_maps;
903 935

	
904 936
    typedef std::vector<std::pair<std::string, 
905 937
      _writer_bits::ValueStorageBase*> > Attributes;
906 938
    Attributes _attributes;
907 939

	
908 940
    bool _skip_nodes;
909 941
    bool _skip_edges;
910 942

	
911 943
  public:
912 944

	
913 945
    /// \brief Constructor
914 946
    ///
915 947
    /// Construct a directed graph writer, which writes to the given
916 948
    /// output stream.
917
    GraphWriter(std::ostream& is, Graph& graph) 
949
    GraphWriter(std::ostream& is, const Graph& graph) 
918 950
      : _os(&is), local_os(false), _graph(graph),
919 951
	_skip_nodes(false), _skip_edges(false) {}
920 952

	
921 953
    /// \brief Constructor
922 954
    ///
923 955
    /// Construct a directed graph writer, which writes to the given
924 956
    /// output file.
925
    GraphWriter(const std::string& fn, Graph& graph) 
957
    GraphWriter(const std::string& fn, const Graph& graph) 
926 958
      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
927 959
	_skip_nodes(false), _skip_edges(false) {}
928 960

	
929 961
    /// \brief Constructor
930 962
    ///
931 963
    /// Construct a directed graph writer, which writes to the given
932 964
    /// output file.
933
    GraphWriter(const char* fn, Graph& graph) 
965
    GraphWriter(const char* fn, const Graph& graph) 
934 966
      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
935 967
	_skip_nodes(false), _skip_edges(false) {}
936 968

	
937
    /// \brief Copy constructor
938
    ///
939
    /// The copy constructor transfers all data from the other writer,
940
    /// therefore the copied writer will not be usable more. 
941
    GraphWriter(GraphWriter& other) 
942
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
943
	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
944

	
945
      other._os = 0;
946
      other.local_os = false;
947

	
948
      _node_index.swap(other._node_index);
949
      _edge_index.swap(other._edge_index);
950

	
951
      _node_maps.swap(other._node_maps);
952
      _edge_maps.swap(other._edge_maps);
953
      _attributes.swap(other._attributes);
954

	
955
      _nodes_caption = other._nodes_caption;
956
      _edges_caption = other._edges_caption;
957
      _attributes_caption = other._attributes_caption;
958
    }
959

	
960 969
    /// \brief Destructor
961 970
    ~GraphWriter() {
962 971
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
963 972
	   it != _node_maps.end(); ++it) {
964 973
	delete it->second;
965 974
      }
966 975

	
967 976
      for (typename EdgeMaps::iterator it = _edge_maps.begin(); 
968 977
	   it != _edge_maps.end(); ++it) {
969 978
	delete it->second;
970 979
      }
971 980

	
972 981
      for (typename Attributes::iterator it = _attributes.begin(); 
973 982
	   it != _attributes.end(); ++it) {
974 983
	delete it->second;
975 984
      }
976 985

	
977 986
      if (local_os) {
978 987
	delete _os;
979 988
      }
980 989
    }
990
    
991
  private:
981 992

	
982
  private:
983
    
993
    friend GraphWriter<Graph> graphWriter<>(std::ostream& os, 
994
					    const Graph& graph);    
995
    friend GraphWriter<Graph> graphWriter<>(const std::string& fn, 
996
					    const Graph& graph);   
997
    friend GraphWriter<Graph> graphWriter<>(const char *fn, 
998
					    const Graph& graph);    
999

	
1000
    GraphWriter(GraphWriter& other) 
1001
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
1002
	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1003

	
1004
      other._os = 0;
1005
      other.local_os = false;
1006

	
1007
      _node_index.swap(other._node_index);
1008
      _edge_index.swap(other._edge_index);
1009

	
1010
      _node_maps.swap(other._node_maps);
1011
      _edge_maps.swap(other._edge_maps);
1012
      _attributes.swap(other._attributes);
1013

	
1014
      _nodes_caption = other._nodes_caption;
1015
      _edges_caption = other._edges_caption;
1016
      _attributes_caption = other._attributes_caption;
1017
    }
1018

	
984 1019
    GraphWriter& operator=(const GraphWriter&);
985 1020

	
986 1021
  public:
987 1022

	
988 1023
    /// \name Writing rules
989 1024
    /// @{
990 1025
    
991 1026
    /// \brief Node map reading rule
992 1027
    ///
993 1028
    /// Add a node map reading rule to the writer.
994 1029
    template <typename Map>
995 1030
    GraphWriter& nodeMap(const std::string& caption, const Map& map) {
996 1031
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
997 1032
      _writer_bits::MapStorageBase<Node>* storage = 
998 1033
	new _writer_bits::MapStorage<Node, Map>(map);
999 1034
      _node_maps.push_back(std::make_pair(caption, storage));
1000 1035
      return *this;
1001 1036
    }
1002 1037

	
1003 1038
    /// \brief Node map writing rule
1004 1039
    ///
1005 1040
    /// Add a node map writing rule with specialized converter to the
1006 1041
    /// writer.
1007 1042
    template <typename Map, typename Converter>
... ...
@@ -1389,45 +1424,45 @@
1389 1424
	writeNodes();
1390 1425
      } else {
1391 1426
	createNodeIndex();
1392 1427
      }
1393 1428
      if (!_skip_edges) {      
1394 1429
	writeEdges();
1395 1430
      } else {
1396 1431
	createEdgeIndex();
1397 1432
      }
1398 1433
      writeAttributes();
1399 1434
    }
1400 1435

	
1401 1436
    /// \brief Gives back the stream of the writer
1402 1437
    ///
1403 1438
    /// Gives back the stream of the writer
1404 1439
    std::ostream& ostream() {
1405 1440
      return *_os;
1406 1441
    }
1407 1442

	
1408 1443
    /// @}
1409 1444
  };
1410 1445

	
1411 1446
  /// \relates GraphWriter
1412 1447
  template <typename Graph>
1413
  GraphWriter<Graph> graphWriter(std::ostream& os, Graph& graph) {
1448
  GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph) {
1414 1449
    GraphWriter<Graph> tmp(os, graph);
1415 1450
    return tmp;
1416 1451
  }
1417 1452

	
1418 1453
  /// \relates GraphWriter
1419 1454
  template <typename Graph>
1420
  GraphWriter<Graph> graphWriter(const std::string& fn, Graph& graph) {
1455
  GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph) {
1421 1456
    GraphWriter<Graph> tmp(fn, graph);
1422 1457
    return tmp;
1423 1458
  }
1424 1459

	
1425 1460
  /// \relates GraphWriter
1426 1461
  template <typename Graph>
1427
  GraphWriter<Graph> graphWriter(const char* fn, Graph& graph) {
1462
  GraphWriter<Graph> graphWriter(const char* fn, const Graph& graph) {
1428 1463
    GraphWriter<Graph> tmp(fn, graph);
1429 1464
    return tmp;
1430 1465
  }
1431 1466
}
1432 1467

	
1433 1468
#endif
0 comments (0 inline)