lemon/lemon_reader.h
changeset 1493 94535d1833b5
parent 1477 0d32f7947a00
child 1494 ae55ba000ebb
equal deleted inserted replaced
2:44cbc38f09a9 3:021727a9004a
    47     class ItemIdReader {
    47     class ItemIdReader {
    48     public:
    48     public:
    49 
    49 
    50       bool isIdReader() { return true; }
    50       bool isIdReader() { return true; }
    51 
    51 
    52       Item readId(std::istream&, Item) { return Item();}
    52       void readId(std::istream&, Item&) {}
    53       
    53       
    54       template <class _ItemIdReader>
    54       template <class _ItemIdReader>
    55       struct Constraints {
    55       struct Constraints {
    56 	void constraints() {
    56 	void constraints() {
    57 	  bool b = reader.isIdReader();
    57 	  bool b = reader.isIdReader();
    58 	  ignore_unused_variable_warning(b);
    58 	  ignore_unused_variable_warning(b);
    59 	  Item item = reader.readId(is, Item());
    59 	  Item item;
       
    60 	  reader.readId(is, item);
    60 	}
    61 	}
    61 	_ItemIdReader& reader;
    62 	_ItemIdReader& reader;
       
    63 	std::istream& is;
       
    64       };
       
    65 
       
    66     };
       
    67 
       
    68     template <typename Item>
       
    69     class ItemReader {
       
    70     public:
       
    71       void read(std::istream&, Item&) {}
       
    72       
       
    73       template <class _ItemReader>
       
    74       struct Constraints {
       
    75 	void constraints() {
       
    76 	  Item item;
       
    77 	  reader.read(is, item);
       
    78 	}
       
    79 	_ItemReader& reader;
    62 	std::istream& is;
    80 	std::istream& is;
    63       };
    81       };
    64 
    82 
    65     };
    83     };
    66   
    84   
   567 
   585 
   568       IdReader(const BoxedIdReader& _boxedIdReader) 
   586       IdReader(const BoxedIdReader& _boxedIdReader) 
   569 	: boxedIdReader(_boxedIdReader) {}
   587 	: boxedIdReader(_boxedIdReader) {}
   570 
   588 
   571       virtual Item read(std::istream& is) const {
   589       virtual Item read(std::istream& is) const {
   572 	return boxedIdReader.readId(is, Item());
   590 	Item item;
       
   591 	boxedIdReader.readId(is, item);
       
   592 	return item;
   573       }
   593       }
   574 
   594 
   575       virtual bool isIdReader() const {
   595       virtual bool isIdReader() const {
   576 	return boxedIdReader.isIdReader();
   596 	return boxedIdReader.isIdReader();
   577       }
   597       }
   694   private:
   714   private:
   695 
   715 
   696     template <typename Reader, typename Map, typename MapParameter>
   716     template <typename Reader, typename Map, typename MapParameter>
   697     NodeSetReader& _readMap(std::string name, MapParameter map, 
   717     NodeSetReader& _readMap(std::string name, MapParameter map, 
   698 			    const Reader& reader = Reader()) {
   718 			    const Reader& reader = Reader()) {
       
   719       checkConcept<concept::WriteMap<Node, typename Map::Value>, Map>();
       
   720       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
   699       if (readers.find(name) != readers.end()) {
   721       if (readers.find(name) != readers.end()) {
   700 	ErrorMessage msg;
   722 	ErrorMessage msg;
   701 	msg << "Multiple read rule for node map: " << name;
   723 	msg << "Multiple read rule for node map: " << name;
   702 	throw IOParameterError(msg.message());
   724 	throw IOParameterError(msg.message());
   703       }
   725       }
   780 
   802 
   781     /// \brief Gives back the node by its id.
   803     /// \brief Gives back the node by its id.
   782     ///
   804     ///
   783     /// It reads an id from the stream and gives back which node belongs to
   805     /// It reads an id from the stream and gives back which node belongs to
   784     /// it. It is possible only if there was read an "id" named map.
   806     /// it. It is possible only if there was read an "id" named map.
   785     Node readId(std::istream& is, Node = Node()) const {
   807     void readId(std::istream& is, Node& node) const {
   786       return inverter->read(is);
   808       node = inverter->read(is);
   787     } 
   809     } 
   788 
   810 
   789   private:
   811   private:
   790 
   812 
   791     typedef std::map<std::string, ReaderBase<Node>*> MapReaders;
   813     typedef std::map<std::string, ReaderBase<Node>*> MapReaders;
   902   private:
   924   private:
   903 
   925 
   904     template <typename Reader, typename Map, typename MapParameter>
   926     template <typename Reader, typename Map, typename MapParameter>
   905     EdgeSetReader& _readMap(std::string name, MapParameter map, 
   927     EdgeSetReader& _readMap(std::string name, MapParameter map, 
   906 			    const Reader& reader = Reader()) {
   928 			    const Reader& reader = Reader()) {
       
   929       checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
       
   930       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
   907       if (readers.find(name) != readers.end()) {
   931       if (readers.find(name) != readers.end()) {
   908 	ErrorMessage msg;
   932 	ErrorMessage msg;
   909 	msg << "Multiple read rule for edge map: " << name;
   933 	msg << "Multiple read rule for edge map: " << name;
   910 	throw IOParameterError(msg.message());
   934 	throw IOParameterError(msg.message());
   911       }
   935       }
   993 
  1017 
   994     /// \brief Gives back the edge by its id.
  1018     /// \brief Gives back the edge by its id.
   995     ///
  1019     ///
   996     /// It reads an id from the stream and gives back which edge belongs to
  1020     /// It reads an id from the stream and gives back which edge belongs to
   997     /// it. It is possible only if there was read an "id" named map.
  1021     /// it. It is possible only if there was read an "id" named map.
   998     Edge readId(std::istream& is, Edge = Edge()) const {
  1022     void readId(std::istream& is, Edge& edge) const {
   999       return inverter->read(is);
  1023       edge = inverter->read(is);
  1000     } 
  1024     } 
  1001 
  1025 
  1002   private:
  1026   private:
  1003 
  1027 
  1004     typedef std::map<std::string, ReaderBase<Edge>*> MapReaders;
  1028     typedef std::map<std::string, ReaderBase<Edge>*> MapReaders;
  1122   private:
  1146   private:
  1123 
  1147 
  1124     template <typename Reader, typename Map, typename MapParameter>
  1148     template <typename Reader, typename Map, typename MapParameter>
  1125     UndirEdgeSetReader& _readMap(std::string name, MapParameter map,
  1149     UndirEdgeSetReader& _readMap(std::string name, MapParameter map,
  1126 				 const Reader& reader = Reader()) {
  1150 				 const Reader& reader = Reader()) {
       
  1151       checkConcept<concept::WriteMap<UndirEdge, typename Map::Value>, Map>();
       
  1152       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
  1127       if (readers.find(name) != readers.end()) {
  1153       if (readers.find(name) != readers.end()) {
  1128 	ErrorMessage msg;
  1154 	ErrorMessage msg;
  1129 	msg << "Multiple read rule for edge map: " << name;
  1155 	msg << "Multiple read rule for edge map: " << name;
  1130 	throw IOParameterError(msg.message());
  1156 	throw IOParameterError(msg.message());
  1131       }
  1157       }
  1188 
  1214 
  1189   private:
  1215   private:
  1190 
  1216 
  1191     template <typename Reader, typename Map, typename MapParameter>
  1217     template <typename Reader, typename Map, typename MapParameter>
  1192     UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map,
  1218     UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map,
  1193 				    const Reader& reader = Reader()) {
  1219 				    const Reader& reader = Reader()) { 
       
  1220       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
       
  1221       checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
  1194       readMap("+" + name, 
  1222       readMap("+" + name, 
  1195 	      _reader_bits::writeComposeMap(map, forwardMap(graph)), reader);
  1223 	      _reader_bits::writeComposeMap(map, forwardMap(graph)), reader);
  1196       readMap("-" + name, 
  1224       readMap("-" + name, 
  1197 	      _reader_bits::writeComposeMap(map, backwardMap(graph)), reader);
  1225 	      _reader_bits::writeComposeMap(map, backwardMap(graph)), reader);
  1198       return *this;      
  1226       return *this;      
  1273 
  1301 
  1274     /// \brief Gives back the undirected edge by its id.
  1302     /// \brief Gives back the undirected edge by its id.
  1275     ///
  1303     ///
  1276     /// It reads an id from the stream and gives back which undirected edge 
  1304     /// It reads an id from the stream and gives back which undirected edge 
  1277     /// belongs to it. It is possible only if there was read an "id" named map.
  1305     /// belongs to it. It is possible only if there was read an "id" named map.
  1278     UndirEdge readId(std::istream& is, UndirEdge = UndirEdge()) const {
  1306     void readId(std::istream& is, UndirEdge& undirEdge) const {
  1279       return inverter->read(is);
  1307       undirEdge = inverter->read(is);
  1280     } 
  1308     } 
  1281 
  1309 
  1282     /// \brief Gives back the directed edge by its id.
  1310     /// \brief Gives back the directed edge by its id.
  1283     ///
  1311     ///
  1284     /// It reads an id from the stream and gives back which directed edge 
  1312     /// It reads an id from the stream and gives back which directed edge 
  1285     /// belongs to it. The directed edge id is the \c '+' or \c '-' character
  1313     /// belongs to it. The directed edge id is the \c '+' or \c '-' character
  1286     /// and the undirected edge id. It is possible only if there was read 
  1314     /// and the undirected edge id. It is possible only if there was read 
  1287     /// an "id" named map.
  1315     /// an "id" named map.
  1288     Edge readId(std::istream& is, Edge = Edge()) const {
  1316     void readId(std::istream& is, Edge& edge) const {
  1289       char c;
  1317       char c;
  1290       is >> c;
  1318       is >> c;
  1291       UndirEdge undirEdge = inverter->read(is);
  1319       UndirEdge undirEdge = inverter->read(is);
  1292       if (c == '+') {
  1320       if (c == '+') {
  1293 	return graph.edgeWithSource(undirEdge, graph.source(undirEdge));
  1321 	edge = graph.edgeWithSource(undirEdge, graph.source(undirEdge));
  1294       } else if (c == '-') {
  1322       } else if (c == '-') {
  1295 	return graph.edgeWithSource(undirEdge, graph.target(undirEdge));
  1323         edge = graph.edgeWithSource(undirEdge, graph.target(undirEdge));
  1296       } else {
  1324       } else {
  1297 	throw DataFormatError("Wrong id format for edge "
  1325 	throw DataFormatError("Wrong id format for edge "
  1298 			      "in undirected edgeset");
  1326 			      "in undirected edgeset");
  1299       }
  1327       }
  1300     } 
  1328     } 
  1338     template <typename _IdReader>
  1366     template <typename _IdReader>
  1339     NodeReader(LemonReader& _reader, const _IdReader& _idReader, 
  1367     NodeReader(LemonReader& _reader, const _IdReader& _idReader, 
  1340 	       const std::string& _id = std::string()) 
  1368 	       const std::string& _id = std::string()) 
  1341       : Parent(_reader), id(_id) {
  1369       : Parent(_reader), id(_id) {
  1342       checkConcept<_reader_bits::ItemIdReader<Node>, _IdReader>();
  1370       checkConcept<_reader_bits::ItemIdReader<Node>, _IdReader>();
  1343       idReader.reset(new IdReader<Node, _IdReader>(_idReader));
  1371       nodeIdReader.reset(new IdReader<Node, _IdReader>(_idReader));
  1344     }
  1372     }
  1345 
  1373 
  1346     /// \brief Destructor.
  1374     /// \brief Destructor.
  1347     ///
  1375     ///
  1348     /// Destructor for NodeReader.
  1376     /// Destructor for NodeReader.
  1383 
  1411 
  1384     /// \brief Reader function of the section.
  1412     /// \brief Reader function of the section.
  1385     ///
  1413     ///
  1386     /// It reads the content of the section.
  1414     /// It reads the content of the section.
  1387     virtual void read(std::istream& is) {
  1415     virtual void read(std::istream& is) {
  1388       if (!idReader->isIdReader()) {
  1416       if (!nodeIdReader->isIdReader()) {
  1389 	throw DataFormatError("Cannot find nodeset or ID map");
  1417 	throw DataFormatError("Cannot find nodeset or ID map");
  1390       }
  1418       }
  1391       std::string line;
  1419       std::string line;
  1392       while (getline(is, line)) {
  1420       while (getline(is, line)) {
  1393 	std::istringstream ls(line);
  1421 	std::istringstream ls(line);
  1394 	std::string id;
  1422 	std::string id;
  1395 	ls >> id;
  1423 	ls >> id;
  1396 	typename NodeReaders::iterator it = readers.find(id);
  1424 	typename NodeReaders::iterator it = readers.find(id);
  1397 	if (it != readers.end()) {
  1425 	if (it != readers.end()) {
  1398 	  *(it->second) = idReader->read(ls); 
  1426 	  *(it->second) = nodeIdReader->read(ls); 
  1399 	}	
  1427 	}	
  1400       }
  1428       }
  1401     }
  1429     }
  1402     
  1430     
  1403   private:
  1431   private:
  1404 
  1432 
  1405     std::string id;
  1433     std::string id;
  1406 
  1434 
  1407     typedef std::map<std::string, Node*> NodeReaders;
  1435     typedef std::map<std::string, Node*> NodeReaders;
  1408     NodeReaders readers;
  1436     NodeReaders readers;
  1409     std::auto_ptr<IdReaderBase<Node> > idReader;
  1437     std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
  1410   };
  1438   };
  1411 
  1439 
  1412   /// \ingroup io_group
  1440   /// \ingroup io_group
  1413   /// \brief SectionReader for reading labeled edges.
  1441   /// \brief SectionReader for reading labeled edges.
  1414   ///
  1442   ///
  1435     template <typename _IdReader>
  1463     template <typename _IdReader>
  1436     EdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
  1464     EdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
  1437 	       const std::string& _id = std::string()) 
  1465 	       const std::string& _id = std::string()) 
  1438       : Parent(_reader), id(_id) {
  1466       : Parent(_reader), id(_id) {
  1439       checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
  1467       checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
  1440       idReader.reset(new IdReader<Edge, _IdReader>(_idReader));
  1468       edgeIdReader.reset(new IdReader<Edge, _IdReader>(_idReader));
  1441     }
  1469     }
  1442 
  1470 
  1443     /// \brief Destructor.
  1471     /// \brief Destructor.
  1444     ///
  1472     ///
  1445     /// Destructor for EdgeReader.
  1473     /// Destructor for EdgeReader.
  1479 
  1507 
  1480     /// \brief Reader function of the section.
  1508     /// \brief Reader function of the section.
  1481     ///
  1509     ///
  1482     /// It reads the content of the section.
  1510     /// It reads the content of the section.
  1483     virtual void read(std::istream& is) {
  1511     virtual void read(std::istream& is) {
  1484       if (!idReader->isIdReader()) {
  1512       if (!edgeIdReader->isIdReader()) {
  1485 	throw DataFormatError("Cannot find edgeset or ID map");
  1513 	throw DataFormatError("Cannot find edgeset or ID map");
  1486       }
  1514       }
  1487       std::string line;
  1515       std::string line;
  1488       while (getline(is, line)) {
  1516       while (getline(is, line)) {
  1489 	std::istringstream ls(line);
  1517 	std::istringstream ls(line);
  1490 	std::string id;
  1518 	std::string id;
  1491 	ls >> id;
  1519 	ls >> id;
  1492 	typename EdgeReaders::iterator it = readers.find(id);
  1520 	typename EdgeReaders::iterator it = readers.find(id);
  1493 	if (it != readers.end()) {
  1521 	if (it != readers.end()) {
  1494 	  *(it->second) = idReader->read(ls); 
  1522 	  *(it->second) = edgeIdReader->read(ls); 
  1495 	}	
  1523 	}	
  1496       }
  1524       }
  1497     }
  1525     }
  1498     
  1526     
  1499   private:
  1527   private:
  1500 
  1528 
  1501     std::string id;
  1529     std::string id;
  1502 
  1530 
  1503     typedef std::map<std::string, Edge*> EdgeReaders;
  1531     typedef std::map<std::string, Edge*> EdgeReaders;
  1504     EdgeReaders readers;
  1532     EdgeReaders readers;
  1505     std::auto_ptr<IdReaderBase<Edge> > idReader;
  1533     std::auto_ptr<IdReaderBase<Edge> > edgeIdReader;
  1506   };
  1534   };
  1507 
  1535 
  1508   /// \ingroup io_group
  1536   /// \ingroup io_group
  1509   /// \brief SectionReader for reading labeled undirected edges.
  1537   /// \brief SectionReader for reading labeled undirected edges.
  1510   ///
  1538   ///
  1686     ///
  1714     ///
  1687     /// Add an attribute reader command for the reader.
  1715     /// Add an attribute reader command for the reader.
  1688     template <typename Reader, typename Value>
  1716     template <typename Reader, typename Value>
  1689     AttributeReader& readAttribute(const std::string& name, Value& value,
  1717     AttributeReader& readAttribute(const std::string& name, Value& value,
  1690 				   const Reader& reader = Reader()) {
  1718 				   const Reader& reader = Reader()) {
       
  1719       checkConcept<_reader_bits::ItemReader<Value>, Reader>();
  1691       if (readers.find(name) != readers.end()) {
  1720       if (readers.find(name) != readers.end()) {
  1692 	ErrorMessage msg;
  1721 	ErrorMessage msg;
  1693 	msg << "Multiple read rule for attribute: " << name;
  1722 	msg << "Multiple read rule for attribute: " << name;
  1694 	throw IOParameterError(msg.message());
  1723 	throw IOParameterError(msg.message());
  1695       }
  1724       }