gravatar
deba@inf.elte.hu
deba@inf.elte.hu
New skip*() functions in (Dig|G)raphReader
0 1 0
default
1 file changed with 78 insertions and 12 deletions:
↑ Collapse diff ↑
Show white space 48 line context
... ...
@@ -458,84 +458,91 @@
458 458

	
459 459
    typedef std::map<std::string, Node> NodeIndex;
460 460
    NodeIndex _node_index;
461 461
    typedef std::map<std::string, Arc> ArcIndex;
462 462
    ArcIndex _arc_index;
463 463
    
464 464
    typedef std::vector<std::pair<std::string, 
465 465
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
466 466
    NodeMaps _node_maps; 
467 467

	
468 468
    typedef std::vector<std::pair<std::string,
469 469
      _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
470 470
    ArcMaps _arc_maps;
471 471

	
472 472
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
473 473
      Attributes;
474 474
    Attributes _attributes;
475 475

	
476 476
    typedef std::map<std::string, _reader_bits::Section*> Sections;
477 477
    Sections _sections;
478 478

	
479 479
    bool _use_nodes;
480 480
    bool _use_arcs;
481 481

	
482
    bool _skip_nodes;
483
    bool _skip_arcs;
484

	
482 485
    int line_num;
483 486
    std::istringstream line;
484 487

	
485 488
  public:
486 489

	
487 490
    /// \brief Constructor
488 491
    ///
489 492
    /// Construct a directed graph reader, which reads from the given
490 493
    /// input stream.
491 494
    DigraphReader(std::istream& is, Digraph& digraph) 
492 495
      : _is(&is), local_is(false), _digraph(digraph),
493
	_use_nodes(false), _use_arcs(false) {}
496
	_use_nodes(false), _use_arcs(false),
497
	_skip_nodes(false), _skip_arcs(false) {}
494 498

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

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

	
519 526
      other._is = 0;
520 527
      other.local_is = false;
521 528
      
522 529
      _node_index.swap(other._node_index);
523 530
      _arc_index.swap(other._arc_index);
524 531

	
525 532
      _node_maps.swap(other._node_maps);
526 533
      _arc_maps.swap(other._arc_maps);
527 534
      _attributes.swap(other._attributes);
528 535

	
529 536
      _nodes_caption = other._nodes_caption;
530 537
      _arcs_caption = other._arcs_caption;
531 538
      _attributes_caption = other._attributes_caption;
532 539

	
533 540
      _sections.swap(other._sections);
534 541
    }
535 542

	
536 543
    /// \brief Destructor
537 544
    ~DigraphReader() {
538 545
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
539 546
	   it != _node_maps.end(); ++it) {
540 547
	delete it->second;
541 548
      }
... ...
@@ -826,48 +833,74 @@
826 833
      _writer_bits::DefaultConverter<typename Map::Value> converter;
827 834
      for (ArcIt a(_digraph); a != INVALID; ++a) {
828 835
	_arc_index.insert(std::make_pair(converter(map[a]), a));
829 836
      }
830 837
      return *this;
831 838
    }
832 839

	
833 840
    /// \brief Use previously constructed arc set
834 841
    ///
835 842
    /// Use previously constructed arc set, and specify the arc
836 843
    /// label map and a functor which converts the label map values to
837 844
    /// std::string.
838 845
    template <typename Map, typename Converter>
839 846
    DigraphReader& useArcs(const Map& map, 
840 847
			    const Converter& converter = Converter()) {
841 848
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
842 849
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); 
843 850
      _use_arcs = true;
844 851
      for (ArcIt a(_digraph); a != INVALID; ++a) {
845 852
	_arc_index.insert(std::make_pair(converter(map[a]), a));
846 853
      }
847 854
      return *this;
848 855
    }
849 856

	
857
    /// \brief Skips the reading of node section
858
    ///
859
    /// Omit the reading of the node section. This implies that each node
860
    /// map reading rule will be abanoned, and the nodes of the graph
861
    /// will not be constructed, which usually cause that the arc set
862
    /// could not be read due to lack of node name
863
    /// resolving. Therefore, the \c skipArcs() should be used too, or
864
    /// the useNodes() member function should be used to specify the
865
    /// label of the nodes.
866
    DigraphReader& skipNodes() {
867
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 
868
      _skip_nodes = true;
869
      return *this;
870
    }
871

	
872
    /// \brief Skips the reading of arc section
873
    ///
874
    /// Omit the reading of the arc section. This implies that each arc
875
    /// map reading rule will be abanoned, and the arcs of the graph
876
    /// will not be constructed.
877
    DigraphReader& skipArcs() {
878
      LEMON_ASSERT(!_skip_arcs, "Skip arcs already set"); 
879
      _skip_arcs = true;
880
      return *this;
881
    }
882

	
850 883
    /// @}
851 884

	
852 885
  private:
853 886

	
854 887
    bool readLine() {
855 888
      std::string str;
856 889
      while(++line_num, std::getline(*_is, str)) {
857 890
	line.clear(); line.str(str);
858 891
	char c;
859 892
	if (line >> std::ws >> c && c != '#') {
860 893
	  line.putback(c);
861 894
	  return true;
862 895
	}
863 896
      }
864 897
      return false;
865 898
    }
866 899

	
867 900
    bool readSuccess() {
868 901
      return static_cast<bool>(*_is);
869 902
    }
870 903
    
871 904
    void skipSection() {
872 905
      char c;
873 906
      while (readSuccess() && line >> c && c != '@') {
... ...
@@ -1131,50 +1164,50 @@
1131 1164
      for (typename Attributes::iterator it = _attributes.begin();
1132 1165
	   it != _attributes.end(); ++it) {
1133 1166
	if (read_attr.find(it->first) == read_attr.end()) {
1134 1167
	  std::ostringstream msg;
1135 1168
	  msg << "Attribute not found in file: " << it->first;
1136 1169
	  throw DataFormatError(msg.str().c_str());
1137 1170
	}	
1138 1171
      }
1139 1172
    }
1140 1173

	
1141 1174
  public:
1142 1175

	
1143 1176
    /// \name Execution of the reader    
1144 1177
    /// @{
1145 1178

	
1146 1179
    /// \brief Start the batch processing
1147 1180
    ///
1148 1181
    /// This function starts the batch processing
1149 1182
    void run() {
1150 1183
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1151 1184
      if (!*_is) {
1152 1185
	throw DataFormatError("Cannot find file");
1153 1186
      }
1154 1187
      
1155
      bool nodes_done = false;
1156
      bool arcs_done = false;
1188
      bool nodes_done = _skip_nodes;
1189
      bool arcs_done = _skip_arcs;
1157 1190
      bool attributes_done = false;
1158 1191
      std::set<std::string> extra_sections;
1159 1192

	
1160 1193
      line_num = 0;      
1161 1194
      readLine();
1162 1195
      skipSection();
1163 1196

	
1164 1197
      while (readSuccess()) {
1165 1198
	try {
1166 1199
	  char c;
1167 1200
	  std::string section, caption;
1168 1201
	  line >> c;
1169 1202
	  _reader_bits::readToken(line, section);
1170 1203
	  _reader_bits::readToken(line, caption);
1171 1204

	
1172 1205
	  if (line >> c) 
1173 1206
	    throw DataFormatError("Extra character on the end of line");
1174 1207

	
1175 1208
	  if (section == "nodes" && !nodes_done) {
1176 1209
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
1177 1210
	      readNodes();
1178 1211
	      nodes_done = true;
1179 1212
	    }
1180 1213
	  } else if ((section == "arcs" || section == "edges") && 
... ...
@@ -1274,84 +1307,91 @@
1274 1307

	
1275 1308
    typedef std::map<std::string, Node> NodeIndex;
1276 1309
    NodeIndex _node_index;
1277 1310
    typedef std::map<std::string, Edge> EdgeIndex;
1278 1311
    EdgeIndex _edge_index;
1279 1312
    
1280 1313
    typedef std::vector<std::pair<std::string, 
1281 1314
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
1282 1315
    NodeMaps _node_maps; 
1283 1316

	
1284 1317
    typedef std::vector<std::pair<std::string,
1285 1318
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1286 1319
    EdgeMaps _edge_maps;
1287 1320

	
1288 1321
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
1289 1322
      Attributes;
1290 1323
    Attributes _attributes;
1291 1324

	
1292 1325
    typedef std::map<std::string, _reader_bits::Section*> Sections;
1293 1326
    Sections _sections;
1294 1327

	
1295 1328
    bool _use_nodes;
1296 1329
    bool _use_edges;
1297 1330

	
1331
    bool _skip_nodes;
1332
    bool _skip_edges;
1333

	
1298 1334
    int line_num;
1299 1335
    std::istringstream line;
1300 1336

	
1301 1337
  public:
1302 1338

	
1303 1339
    /// \brief Constructor
1304 1340
    ///
1305 1341
    /// Construct a undirected graph reader, which reads from the given
1306 1342
    /// input stream.
1307 1343
    GraphReader(std::istream& is, Graph& graph) 
1308 1344
      : _is(&is), local_is(false), _graph(graph),
1309
	_use_nodes(false), _use_edges(false) {}
1345
	_use_nodes(false), _use_edges(false),
1346
	_skip_nodes(false), _skip_edges(false) {}
1310 1347

	
1311 1348
    /// \brief Constructor
1312 1349
    ///
1313 1350
    /// Construct a undirected graph reader, which reads from the given
1314 1351
    /// file.
1315 1352
    GraphReader(const std::string& fn, Graph& graph) 
1316 1353
      : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph),
1317
    	_use_nodes(false), _use_edges(false) {}
1354
    	_use_nodes(false), _use_edges(false),
1355
	_skip_nodes(false), _skip_edges(false) {}
1318 1356
    
1319 1357
    /// \brief Constructor
1320 1358
    ///
1321 1359
    /// Construct a undirected graph reader, which reads from the given
1322 1360
    /// file.
1323 1361
    GraphReader(const char* fn, Graph& graph) 
1324 1362
      : _is(new std::ifstream(fn)), local_is(true), _graph(graph),
1325
    	_use_nodes(false), _use_edges(false) {}
1363
    	_use_nodes(false), _use_edges(false),
1364
	_skip_nodes(false), _skip_edges(false) {}
1326 1365

	
1327 1366
    /// \brief Copy constructor
1328 1367
    ///
1329 1368
    /// The copy constructor transfers all data from the other reader,
1330 1369
    /// therefore the copied reader will not be usable more. 
1331 1370
    GraphReader(GraphReader& other) 
1332 1371
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1333
	_use_nodes(other._use_nodes), _use_edges(other._use_edges) {
1372
	_use_nodes(other._use_nodes), _use_edges(other._use_edges),
1373
	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1334 1374

	
1335 1375
      other._is = 0;
1336 1376
      other.local_is = false;
1337 1377
      
1338 1378
      _node_index.swap(other._node_index);
1339 1379
      _edge_index.swap(other._edge_index);
1340 1380

	
1341 1381
      _node_maps.swap(other._node_maps);
1342 1382
      _edge_maps.swap(other._edge_maps);
1343 1383
      _attributes.swap(other._attributes);
1344 1384

	
1345 1385
      _nodes_caption = other._nodes_caption;
1346 1386
      _edges_caption = other._edges_caption;
1347 1387
      _attributes_caption = other._attributes_caption;
1348 1388

	
1349 1389
      _sections.swap(other._sections);
1350 1390
    }
1351 1391

	
1352 1392
    /// \brief Destructor
1353 1393
    ~GraphReader() {
1354 1394
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
1355 1395
	   it != _node_maps.end(); ++it) {
1356 1396
	delete it->second;
1357 1397
      }
... ...
@@ -1688,48 +1728,74 @@
1688 1728
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1689 1729
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1690 1730
	_edge_index.insert(std::make_pair(converter(map[a]), a));
1691 1731
      }
1692 1732
      return *this;
1693 1733
    }
1694 1734

	
1695 1735
    /// \brief Use previously constructed edge set
1696 1736
    ///
1697 1737
    /// Use previously constructed edge set, and specify the edge
1698 1738
    /// label map and a functor which converts the label map values to
1699 1739
    /// std::string.
1700 1740
    template <typename Map, typename Converter>
1701 1741
    GraphReader& useEdges(const Map& map, 
1702 1742
			    const Converter& converter = Converter()) {
1703 1743
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1704 1744
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 
1705 1745
      _use_edges = true;
1706 1746
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1707 1747
	_edge_index.insert(std::make_pair(converter(map[a]), a));
1708 1748
      }
1709 1749
      return *this;
1710 1750
    }
1711 1751

	
1752
    /// \brief Skips the reading of node section
1753
    ///
1754
    /// Omit the reading of the node section. This implies that each node
1755
    /// map reading rule will be abanoned, and the nodes of the graph
1756
    /// will not be constructed, which usually cause that the edge set
1757
    /// could not be read due to lack of node name
1758
    /// resolving. Therefore, the \c skipEdges() should be used too, or
1759
    /// the useNodes() member function should be used to specify the
1760
    /// label of the nodes.
1761
    GraphReader& skipNodes() {
1762
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 
1763
      _skip_nodes = true;
1764
      return *this;
1765
    }
1766

	
1767
    /// \brief Skips the reading of edge section
1768
    ///
1769
    /// Omit the reading of the edge section. This implies that each edge
1770
    /// map reading rule will be abanoned, and the edges of the graph
1771
    /// will not be constructed.
1772
    GraphReader& skipEdges() {
1773
      LEMON_ASSERT(!_skip_edges, "Skip edges already set"); 
1774
      _skip_edges = true;
1775
      return *this;
1776
    }
1777

	
1712 1778
    /// @}
1713 1779

	
1714 1780
  private:
1715 1781

	
1716 1782
    bool readLine() {
1717 1783
      std::string str;
1718 1784
      while(++line_num, std::getline(*_is, str)) {
1719 1785
	line.clear(); line.str(str);
1720 1786
	char c;
1721 1787
	if (line >> std::ws >> c && c != '#') {
1722 1788
	  line.putback(c);
1723 1789
	  return true;
1724 1790
	}
1725 1791
      }
1726 1792
      return false;
1727 1793
    }
1728 1794

	
1729 1795
    bool readSuccess() {
1730 1796
      return static_cast<bool>(*_is);
1731 1797
    }
1732 1798
    
1733 1799
    void skipSection() {
1734 1800
      char c;
1735 1801
      while (readSuccess() && line >> c && c != '@') {
... ...
@@ -1991,50 +2057,50 @@
1991 2057
	line.putback(c);
1992 2058
      }
1993 2059
      for (typename Attributes::iterator it = _attributes.begin();
1994 2060
	   it != _attributes.end(); ++it) {
1995 2061
	if (read_attr.find(it->first) == read_attr.end()) {
1996 2062
	  std::ostringstream msg;
1997 2063
	  msg << "Attribute not found in file: " << it->first;
1998 2064
	  throw DataFormatError(msg.str().c_str());
1999 2065
	}	
2000 2066
      }
2001 2067
    }
2002 2068

	
2003 2069
  public:
2004 2070

	
2005 2071
    /// \name Execution of the reader    
2006 2072
    /// @{
2007 2073

	
2008 2074
    /// \brief Start the batch processing
2009 2075
    ///
2010 2076
    /// This function starts the batch processing
2011 2077
    void run() {
2012 2078
      
2013 2079
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2014 2080
      
2015
      bool nodes_done = false;
2016
      bool edges_done = false;
2081
      bool nodes_done = _skip_nodes;
2082
      bool edges_done = _skip_edges;
2017 2083
      bool attributes_done = false;
2018 2084
      std::set<std::string> extra_sections;
2019 2085

	
2020 2086
      line_num = 0;      
2021 2087
      readLine();
2022 2088
      skipSection();
2023 2089

	
2024 2090
      while (readSuccess()) {
2025 2091
	try {
2026 2092
	  char c;
2027 2093
	  std::string section, caption;
2028 2094
	  line >> c;
2029 2095
	  _reader_bits::readToken(line, section);
2030 2096
	  _reader_bits::readToken(line, caption);
2031 2097

	
2032 2098
	  if (line >> c) 
2033 2099
	    throw DataFormatError("Extra character on the end of line");
2034 2100

	
2035 2101
	  if (section == "nodes" && !nodes_done) {
2036 2102
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
2037 2103
	      readNodes();
2038 2104
	      nodes_done = true;
2039 2105
	    }
2040 2106
	  } else if ((section == "edges" || section == "arcs") && 
0 comments (0 inline)