Changeset 165:b4c336c27a03 in lemon-1.2 for lemon
- Timestamp:
- 05/31/08 12:49:18 (16 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- lemon
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/lgf_reader.h
r163 r165 101 101 }; 102 102 103 template <typename _Graph, bool _dir, typename _Map, 104 typename _Converter = DefaultConverter<typename _Map::Value> > 105 class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> { 106 public: 107 typedef _Map Map; 108 typedef _Converter Converter; 109 typedef _Graph Graph; 110 typedef typename Graph::Edge Item; 111 static const bool dir = _dir; 112 113 private: 114 const Graph& _graph; 115 Map& _map; 116 Converter _converter; 117 118 public: 119 GraphArcMapStorage(const Graph& graph, Map& map, 120 const Converter& converter = Converter()) 121 : _graph(graph), _map(map), _converter(converter) {} 122 virtual ~GraphArcMapStorage() {} 123 124 virtual void set(const Item& item ,const std::string& value) { 125 _map.set(_graph.direct(item, dir), _converter(value)); 126 } 127 }; 128 103 129 class ValueStorageBase { 104 130 public: … … 144 170 } 145 171 return it->second; 172 } 173 }; 174 175 template <typename Graph> 176 struct GraphArcLookUpConverter { 177 const Graph& _graph; 178 const std::map<std::string, typename Graph::Edge>& _map; 179 180 GraphArcLookUpConverter(const Graph& graph, 181 const std::map<std::string, 182 typename Graph::Edge>& map) 183 : _graph(graph), _map(map) {} 184 185 typename Graph::Arc operator()(const std::string& str) { 186 if (str.empty() || (str[0] != '+' && str[0] != '-')) { 187 throw DataFormatError("Item must start with '+' or '-'"); 188 } 189 typename std::map<std::string, typename Graph::Edge> 190 ::const_iterator it = _map.find(str.substr(1)); 191 if (it == _map.end()) { 192 throw DataFormatError("Item not found"); 193 } 194 return _graph.direct(it->second, str[0] == '+'); 146 195 } 147 196 }; … … 1181 1230 return tmp; 1182 1231 } 1232 1233 /// \ingroup lemon_io 1234 /// 1235 /// \brief LGF reader for undirected graphs 1236 /// 1237 /// This utility reads an \ref lgf-format "LGF" file. 1238 template <typename _Graph> 1239 class GraphReader { 1240 public: 1241 1242 typedef _Graph Graph; 1243 TEMPLATE_GRAPH_TYPEDEFS(Graph); 1244 1245 private: 1246 1247 1248 std::istream* _is; 1249 bool local_is; 1250 1251 Graph& _graph; 1252 1253 std::string _nodes_caption; 1254 std::string _edges_caption; 1255 std::string _attributes_caption; 1256 1257 typedef std::map<std::string, Node> NodeIndex; 1258 NodeIndex _node_index; 1259 typedef std::map<std::string, Edge> EdgeIndex; 1260 EdgeIndex _edge_index; 1261 1262 typedef std::vector<std::pair<std::string, 1263 _reader_bits::MapStorageBase<Node>*> > NodeMaps; 1264 NodeMaps _node_maps; 1265 1266 typedef std::vector<std::pair<std::string, 1267 _reader_bits::MapStorageBase<Edge>*> > EdgeMaps; 1268 EdgeMaps _edge_maps; 1269 1270 typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 1271 Attributes; 1272 Attributes _attributes; 1273 1274 typedef std::map<std::string, _reader_bits::Section*> Sections; 1275 Sections _sections; 1276 1277 bool _use_nodes; 1278 bool _use_edges; 1279 1280 int line_num; 1281 std::istringstream line; 1282 1283 public: 1284 1285 /// \brief Constructor 1286 /// 1287 /// Construct a undirected graph reader, which reads from the given 1288 /// input stream. 1289 GraphReader(std::istream& is, Graph& graph) 1290 : _is(&is), local_is(false), _graph(graph), 1291 _use_nodes(false), _use_edges(false) {} 1292 1293 /// \brief Constructor 1294 /// 1295 /// Construct a undirected graph reader, which reads from the given 1296 /// file. 1297 GraphReader(const std::string& fn, Graph& graph) 1298 : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph), 1299 _use_nodes(false), _use_edges(false) {} 1300 1301 /// \brief Constructor 1302 /// 1303 /// Construct a undirected graph reader, which reads from the given 1304 /// file. 1305 GraphReader(const char* fn, Graph& graph) 1306 : _is(new std::ifstream(fn)), local_is(true), _graph(graph), 1307 _use_nodes(false), _use_edges(false) {} 1308 1309 /// \brief Copy constructor 1310 /// 1311 /// The copy constructor transfers all data from the other reader, 1312 /// therefore the copied reader will not be usable more. 1313 GraphReader(GraphReader& other) 1314 : _is(other._is), local_is(other.local_is), _graph(other._graph), 1315 _use_nodes(other._use_nodes), _use_edges(other._use_edges) { 1316 1317 other._is = 0; 1318 other.local_is = false; 1319 1320 _node_index.swap(other._node_index); 1321 _edge_index.swap(other._edge_index); 1322 1323 _node_maps.swap(other._node_maps); 1324 _edge_maps.swap(other._edge_maps); 1325 _attributes.swap(other._attributes); 1326 1327 _nodes_caption = other._nodes_caption; 1328 _edges_caption = other._edges_caption; 1329 _attributes_caption = other._attributes_caption; 1330 1331 _sections.swap(other._sections); 1332 } 1333 1334 /// \brief Destructor 1335 ~GraphReader() { 1336 for (typename NodeMaps::iterator it = _node_maps.begin(); 1337 it != _node_maps.end(); ++it) { 1338 delete it->second; 1339 } 1340 1341 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 1342 it != _edge_maps.end(); ++it) { 1343 delete it->second; 1344 } 1345 1346 for (typename Attributes::iterator it = _attributes.begin(); 1347 it != _attributes.end(); ++it) { 1348 delete it->second; 1349 } 1350 1351 for (typename Sections::iterator it = _sections.begin(); 1352 it != _sections.end(); ++it) { 1353 delete it->second; 1354 } 1355 1356 if (local_is) { 1357 delete _is; 1358 } 1359 1360 } 1361 1362 private: 1363 1364 GraphReader& operator=(const GraphReader&); 1365 1366 public: 1367 1368 /// \name Reading rules 1369 /// @{ 1370 1371 /// \brief Node map reading rule 1372 /// 1373 /// Add a node map reading rule to the reader. 1374 template <typename Map> 1375 GraphReader& nodeMap(const std::string& caption, Map& map) { 1376 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); 1377 _reader_bits::MapStorageBase<Node>* storage = 1378 new _reader_bits::MapStorage<Node, Map>(map); 1379 _node_maps.push_back(std::make_pair(caption, storage)); 1380 return *this; 1381 } 1382 1383 /// \brief Node map reading rule 1384 /// 1385 /// Add a node map reading rule with specialized converter to the 1386 /// reader. 1387 template <typename Map, typename Converter> 1388 GraphReader& nodeMap(const std::string& caption, Map& map, 1389 const Converter& converter = Converter()) { 1390 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); 1391 _reader_bits::MapStorageBase<Node>* storage = 1392 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); 1393 _node_maps.push_back(std::make_pair(caption, storage)); 1394 return *this; 1395 } 1396 1397 /// \brief Edge map reading rule 1398 /// 1399 /// Add an edge map reading rule to the reader. 1400 template <typename Map> 1401 GraphReader& edgeMap(const std::string& caption, Map& map) { 1402 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); 1403 _reader_bits::MapStorageBase<Edge>* storage = 1404 new _reader_bits::MapStorage<Edge, Map>(map); 1405 _edge_maps.push_back(std::make_pair(caption, storage)); 1406 return *this; 1407 } 1408 1409 /// \brief Edge map reading rule 1410 /// 1411 /// Add an edge map reading rule with specialized converter to the 1412 /// reader. 1413 template <typename Map, typename Converter> 1414 GraphReader& edgeMap(const std::string& caption, Map& map, 1415 const Converter& converter = Converter()) { 1416 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); 1417 _reader_bits::MapStorageBase<Edge>* storage = 1418 new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter); 1419 _edge_maps.push_back(std::make_pair(caption, storage)); 1420 return *this; 1421 } 1422 1423 /// \brief Arc map reading rule 1424 /// 1425 /// Add an arc map reading rule to the reader. 1426 template <typename Map> 1427 GraphReader& arcMap(const std::string& caption, Map& map) { 1428 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); 1429 _reader_bits::MapStorageBase<Edge>* forward_storage = 1430 new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map); 1431 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 1432 _reader_bits::MapStorageBase<Edge>* backward_storage = 1433 new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map); 1434 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 1435 return *this; 1436 } 1437 1438 /// \brief Arc map reading rule 1439 /// 1440 /// Add an arc map reading rule with specialized converter to the 1441 /// reader. 1442 template <typename Map, typename Converter> 1443 GraphReader& arcMap(const std::string& caption, Map& map, 1444 const Converter& converter = Converter()) { 1445 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); 1446 _reader_bits::MapStorageBase<Edge>* forward_storage = 1447 new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter> 1448 (_graph, map, converter); 1449 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 1450 _reader_bits::MapStorageBase<Edge>* backward_storage = 1451 new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter> 1452 (_graph, map, converter); 1453 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 1454 return *this; 1455 } 1456 1457 /// \brief Attribute reading rule 1458 /// 1459 /// Add an attribute reading rule to the reader. 1460 template <typename Value> 1461 GraphReader& attribute(const std::string& caption, Value& value) { 1462 _reader_bits::ValueStorageBase* storage = 1463 new _reader_bits::ValueStorage<Value>(value); 1464 _attributes.insert(std::make_pair(caption, storage)); 1465 return *this; 1466 } 1467 1468 /// \brief Attribute reading rule 1469 /// 1470 /// Add an attribute reading rule with specialized converter to the 1471 /// reader. 1472 template <typename Value, typename Converter> 1473 GraphReader& attribute(const std::string& caption, Value& value, 1474 const Converter& converter = Converter()) { 1475 _reader_bits::ValueStorageBase* storage = 1476 new _reader_bits::ValueStorage<Value, Converter>(value, converter); 1477 _attributes.insert(std::make_pair(caption, storage)); 1478 return *this; 1479 } 1480 1481 /// \brief Node reading rule 1482 /// 1483 /// Add a node reading rule to reader. 1484 GraphReader& node(const std::string& caption, Node& node) { 1485 typedef _reader_bits::MapLookUpConverter<Node> Converter; 1486 Converter converter(_node_index); 1487 _reader_bits::ValueStorageBase* storage = 1488 new _reader_bits::ValueStorage<Node, Converter>(node, converter); 1489 _attributes.insert(std::make_pair(caption, storage)); 1490 return *this; 1491 } 1492 1493 /// \brief Edge reading rule 1494 /// 1495 /// Add an edge reading rule to reader. 1496 GraphReader& edge(const std::string& caption, Edge& edge) { 1497 typedef _reader_bits::MapLookUpConverter<Edge> Converter; 1498 Converter converter(_edge_index); 1499 _reader_bits::ValueStorageBase* storage = 1500 new _reader_bits::ValueStorage<Edge, Converter>(edge, converter); 1501 _attributes.insert(std::make_pair(caption, storage)); 1502 return *this; 1503 } 1504 1505 /// \brief Arc reading rule 1506 /// 1507 /// Add an arc reading rule to reader. 1508 GraphReader& arc(const std::string& caption, Arc& arc) { 1509 typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter; 1510 Converter converter(_graph, _edge_index); 1511 _reader_bits::ValueStorageBase* storage = 1512 new _reader_bits::ValueStorage<Arc, Converter>(arc, converter); 1513 _attributes.insert(std::make_pair(caption, storage)); 1514 return *this; 1515 } 1516 1517 /// @} 1518 1519 /// \name Select section by name 1520 /// @{ 1521 1522 /// \brief Set \c \@nodes section to be read 1523 /// 1524 /// Set \c \@nodes section to be read 1525 GraphReader& nodes(const std::string& caption) { 1526 _nodes_caption = caption; 1527 return *this; 1528 } 1529 1530 /// \brief Set \c \@edges section to be read 1531 /// 1532 /// Set \c \@edges section to be read 1533 GraphReader& edges(const std::string& caption) { 1534 _edges_caption = caption; 1535 return *this; 1536 } 1537 1538 /// \brief Set \c \@attributes section to be read 1539 /// 1540 /// Set \c \@attributes section to be read 1541 GraphReader& attributes(const std::string& caption) { 1542 _attributes_caption = caption; 1543 return *this; 1544 } 1545 1546 /// @} 1547 1548 /// \name Section readers 1549 /// @{ 1550 1551 /// \brief Add a section processor with line oriented reading 1552 /// 1553 /// In the \e LGF file extra sections can be placed, which contain 1554 /// any data in arbitrary format. These sections can be read with 1555 /// this function line by line. The first parameter is the type 1556 /// descriptor of the section, the second is a functor, which 1557 /// takes just one \c std::string parameter. At the reading 1558 /// process, each line of the section will be given to the functor 1559 /// object. However, the empty lines and the comment lines are 1560 /// filtered out, and the leading whitespaces are stipped from 1561 /// each processed string. 1562 /// 1563 /// For example let's see a section, which contain several 1564 /// integers, which should be inserted into a vector. 1565 ///\code 1566 /// @numbers 1567 /// 12 45 23 1568 /// 4 1569 /// 23 6 1570 ///\endcode 1571 /// 1572 /// The functor is implemented as an struct: 1573 ///\code 1574 /// struct NumberSection { 1575 /// std::vector<int>& _data; 1576 /// NumberSection(std::vector<int>& data) : _data(data) {} 1577 /// void operator()(const std::string& line) { 1578 /// std::istringstream ls(line); 1579 /// int value; 1580 /// while (ls >> value) _data.push_back(value); 1581 /// } 1582 /// }; 1583 /// 1584 /// // ... 1585 /// 1586 /// reader.sectionLines("numbers", NumberSection(vec)); 1587 ///\endcode 1588 template <typename Functor> 1589 GraphReader& sectionLines(const std::string& type, Functor functor) { 1590 LEMON_ASSERT(!type.empty(), "Type is not empty."); 1591 LEMON_ASSERT(_sections.find(type) == _sections.end(), 1592 "Multiple reading of section."); 1593 LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" && 1594 type != "attributes", "Multiple reading of section."); 1595 _sections.insert(std::make_pair(type, 1596 new _reader_bits::LineSection<Functor>(functor))); 1597 return *this; 1598 } 1599 1600 1601 /// \brief Add a section processor with stream oriented reading 1602 /// 1603 /// In the \e LGF file extra sections can be placed, which contain 1604 /// any data in arbitrary format. These sections can be read 1605 /// directly with this function. The first parameter is the type 1606 /// of the section, the second is a functor, which takes an \c 1607 /// std::istream& and an int& parameter, the latter regard to the 1608 /// line number of stream. The functor can read the input while 1609 /// the section go on, and the line number should be modified 1610 /// accordingly. 1611 template <typename Functor> 1612 GraphReader& sectionStream(const std::string& type, Functor functor) { 1613 LEMON_ASSERT(!type.empty(), "Type is not empty."); 1614 LEMON_ASSERT(_sections.find(type) == _sections.end(), 1615 "Multiple reading of section."); 1616 LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" && 1617 type != "attributes", "Multiple reading of section."); 1618 _sections.insert(std::make_pair(type, 1619 new _reader_bits::StreamSection<Functor>(functor))); 1620 return *this; 1621 } 1622 1623 /// @} 1624 1625 /// \name Using previously constructed node or edge set 1626 /// @{ 1627 1628 /// \brief Use previously constructed node set 1629 /// 1630 /// Use previously constructed node set, and specify the node 1631 /// label map. 1632 template <typename Map> 1633 GraphReader& useNodes(const Map& map) { 1634 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 1635 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 1636 _use_nodes = true; 1637 _writer_bits::DefaultConverter<typename Map::Value> converter; 1638 for (NodeIt n(_graph); n != INVALID; ++n) { 1639 _node_index.insert(std::make_pair(converter(map[n]), n)); 1640 } 1641 return *this; 1642 } 1643 1644 /// \brief Use previously constructed node set 1645 /// 1646 /// Use previously constructed node set, and specify the node 1647 /// label map and a functor which converts the label map values to 1648 /// std::string. 1649 template <typename Map, typename Converter> 1650 GraphReader& useNodes(const Map& map, 1651 const Converter& converter = Converter()) { 1652 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 1653 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 1654 _use_nodes = true; 1655 for (NodeIt n(_graph); n != INVALID; ++n) { 1656 _node_index.insert(std::make_pair(converter(map[n]), n)); 1657 } 1658 return *this; 1659 } 1660 1661 /// \brief Use previously constructed edge set 1662 /// 1663 /// Use previously constructed edge set, and specify the edge 1664 /// label map. 1665 template <typename Map> 1666 GraphReader& useEdges(const Map& map) { 1667 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 1668 LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 1669 _use_edges = true; 1670 _writer_bits::DefaultConverter<typename Map::Value> converter; 1671 for (EdgeIt a(_graph); a != INVALID; ++a) { 1672 _edge_index.insert(std::make_pair(converter(map[a]), a)); 1673 } 1674 return *this; 1675 } 1676 1677 /// \brief Use previously constructed edge set 1678 /// 1679 /// Use previously constructed edge set, and specify the edge 1680 /// label map and a functor which converts the label map values to 1681 /// std::string. 1682 template <typename Map, typename Converter> 1683 GraphReader& useEdges(const Map& map, 1684 const Converter& converter = Converter()) { 1685 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 1686 LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 1687 _use_edges = true; 1688 for (EdgeIt a(_graph); a != INVALID; ++a) { 1689 _edge_index.insert(std::make_pair(converter(map[a]), a)); 1690 } 1691 return *this; 1692 } 1693 1694 /// @} 1695 1696 private: 1697 1698 bool readLine() { 1699 std::string str; 1700 while(++line_num, std::getline(*_is, str)) { 1701 line.clear(); line.str(str); 1702 char c; 1703 if (line >> std::ws >> c && c != '#') { 1704 line.putback(c); 1705 return true; 1706 } 1707 } 1708 return false; 1709 } 1710 1711 bool readSuccess() { 1712 return static_cast<bool>(*_is); 1713 } 1714 1715 void skipSection() { 1716 char c; 1717 while (readSuccess() && line >> c && c != '@') { 1718 readLine(); 1719 } 1720 line.putback(c); 1721 } 1722 1723 void readNodes() { 1724 1725 std::vector<int> map_index(_node_maps.size()); 1726 int map_num, label_index; 1727 1728 if (!readLine()) 1729 throw DataFormatError("Cannot find map captions"); 1730 1731 { 1732 std::map<std::string, int> maps; 1733 1734 std::string map; 1735 int index = 0; 1736 while (_reader_bits::readToken(line, map)) { 1737 if (maps.find(map) != maps.end()) { 1738 std::ostringstream msg; 1739 msg << "Multiple occurence of node map: " << map; 1740 throw DataFormatError(msg.str().c_str()); 1741 } 1742 maps.insert(std::make_pair(map, index)); 1743 ++index; 1744 } 1745 1746 for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) { 1747 std::map<std::string, int>::iterator jt = 1748 maps.find(_node_maps[i].first); 1749 if (jt == maps.end()) { 1750 std::ostringstream msg; 1751 msg << "Map not found in file: " << _node_maps[i].first; 1752 throw DataFormatError(msg.str().c_str()); 1753 } 1754 map_index[i] = jt->second; 1755 } 1756 1757 { 1758 std::map<std::string, int>::iterator jt = maps.find("label"); 1759 if (jt == maps.end()) 1760 throw DataFormatError("Label map not found in file"); 1761 label_index = jt->second; 1762 } 1763 map_num = maps.size(); 1764 } 1765 1766 char c; 1767 while (readLine() && line >> c && c != '@') { 1768 line.putback(c); 1769 1770 std::vector<std::string> tokens(map_num); 1771 for (int i = 0; i < map_num; ++i) { 1772 if (!_reader_bits::readToken(line, tokens[i])) { 1773 std::ostringstream msg; 1774 msg << "Column not found (" << i + 1 << ")"; 1775 throw DataFormatError(msg.str().c_str()); 1776 } 1777 } 1778 if (line >> std::ws >> c) 1779 throw DataFormatError("Extra character on the end of line"); 1780 1781 Node n; 1782 if (!_use_nodes) { 1783 n = _graph.addNode(); 1784 _node_index.insert(std::make_pair(tokens[label_index], n)); 1785 } else { 1786 typename std::map<std::string, Node>::iterator it = 1787 _node_index.find(tokens[label_index]); 1788 if (it == _node_index.end()) { 1789 std::ostringstream msg; 1790 msg << "Node with label not found: " << tokens[label_index]; 1791 throw DataFormatError(msg.str().c_str()); 1792 } 1793 n = it->second; 1794 } 1795 1796 for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) { 1797 _node_maps[i].second->set(n, tokens[map_index[i]]); 1798 } 1799 1800 } 1801 if (readSuccess()) { 1802 line.putback(c); 1803 } 1804 } 1805 1806 void readEdges() { 1807 1808 std::vector<int> map_index(_edge_maps.size()); 1809 int map_num, label_index; 1810 1811 if (!readLine()) 1812 throw DataFormatError("Cannot find map captions"); 1813 1814 { 1815 std::map<std::string, int> maps; 1816 1817 std::string map; 1818 int index = 0; 1819 while (_reader_bits::readToken(line, map)) { 1820 if (maps.find(map) != maps.end()) { 1821 std::ostringstream msg; 1822 msg << "Multiple occurence of edge map: " << map; 1823 throw DataFormatError(msg.str().c_str()); 1824 } 1825 maps.insert(std::make_pair(map, index)); 1826 ++index; 1827 } 1828 1829 for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) { 1830 std::map<std::string, int>::iterator jt = 1831 maps.find(_edge_maps[i].first); 1832 if (jt == maps.end()) { 1833 std::ostringstream msg; 1834 msg << "Map not found in file: " << _edge_maps[i].first; 1835 throw DataFormatError(msg.str().c_str()); 1836 } 1837 map_index[i] = jt->second; 1838 } 1839 1840 { 1841 std::map<std::string, int>::iterator jt = maps.find("label"); 1842 if (jt == maps.end()) 1843 throw DataFormatError("Label map not found in file"); 1844 label_index = jt->second; 1845 } 1846 map_num = maps.size(); 1847 } 1848 1849 char c; 1850 while (readLine() && line >> c && c != '@') { 1851 line.putback(c); 1852 1853 std::string source_token; 1854 std::string target_token; 1855 1856 if (!_reader_bits::readToken(line, source_token)) 1857 throw DataFormatError("Source not found"); 1858 1859 if (!_reader_bits::readToken(line, target_token)) 1860 throw DataFormatError("Source not found"); 1861 1862 std::vector<std::string> tokens(map_num); 1863 for (int i = 0; i < map_num; ++i) { 1864 if (!_reader_bits::readToken(line, tokens[i])) { 1865 std::ostringstream msg; 1866 msg << "Column not found (" << i + 1 << ")"; 1867 throw DataFormatError(msg.str().c_str()); 1868 } 1869 } 1870 if (line >> std::ws >> c) 1871 throw DataFormatError("Extra character on the end of line"); 1872 1873 Edge e; 1874 if (!_use_edges) { 1875 1876 typename NodeIndex::iterator it; 1877 1878 it = _node_index.find(source_token); 1879 if (it == _node_index.end()) { 1880 std::ostringstream msg; 1881 msg << "Item not found: " << source_token; 1882 throw DataFormatError(msg.str().c_str()); 1883 } 1884 Node source = it->second; 1885 1886 it = _node_index.find(target_token); 1887 if (it == _node_index.end()) { 1888 std::ostringstream msg; 1889 msg << "Item not found: " << target_token; 1890 throw DataFormatError(msg.str().c_str()); 1891 } 1892 Node target = it->second; 1893 1894 e = _graph.addEdge(source, target); 1895 _edge_index.insert(std::make_pair(tokens[label_index], e)); 1896 } else { 1897 typename std::map<std::string, Edge>::iterator it = 1898 _edge_index.find(tokens[label_index]); 1899 if (it == _edge_index.end()) { 1900 std::ostringstream msg; 1901 msg << "Edge with label not found: " << tokens[label_index]; 1902 throw DataFormatError(msg.str().c_str()); 1903 } 1904 e = it->second; 1905 } 1906 1907 for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) { 1908 _edge_maps[i].second->set(e, tokens[map_index[i]]); 1909 } 1910 1911 } 1912 if (readSuccess()) { 1913 line.putback(c); 1914 } 1915 } 1916 1917 void readAttributes() { 1918 1919 std::set<std::string> read_attr; 1920 1921 char c; 1922 while (readLine() && line >> c && c != '@') { 1923 line.putback(c); 1924 1925 std::string attr, token; 1926 if (!_reader_bits::readToken(line, attr)) 1927 throw DataFormatError("Attribute name not found"); 1928 if (!_reader_bits::readToken(line, token)) 1929 throw DataFormatError("Attribute value not found"); 1930 if (line >> c) 1931 throw DataFormatError("Extra character on the end of line"); 1932 1933 { 1934 std::set<std::string>::iterator it = read_attr.find(attr); 1935 if (it != read_attr.end()) { 1936 std::ostringstream msg; 1937 msg << "Multiple occurence of attribute " << attr; 1938 throw DataFormatError(msg.str().c_str()); 1939 } 1940 read_attr.insert(attr); 1941 } 1942 1943 { 1944 typename Attributes::iterator it = _attributes.lower_bound(attr); 1945 while (it != _attributes.end() && it->first == attr) { 1946 it->second->set(token); 1947 ++it; 1948 } 1949 } 1950 1951 } 1952 if (readSuccess()) { 1953 line.putback(c); 1954 } 1955 for (typename Attributes::iterator it = _attributes.begin(); 1956 it != _attributes.end(); ++it) { 1957 if (read_attr.find(it->first) == read_attr.end()) { 1958 std::ostringstream msg; 1959 msg << "Attribute not found in file: " << it->first; 1960 throw DataFormatError(msg.str().c_str()); 1961 } 1962 } 1963 } 1964 1965 public: 1966 1967 /// \name Execution of the reader 1968 /// @{ 1969 1970 /// \brief Start the batch processing 1971 /// 1972 /// This function starts the batch processing 1973 void run() { 1974 1975 LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); 1976 1977 bool nodes_done = false; 1978 bool edges_done = false; 1979 bool attributes_done = false; 1980 std::set<std::string> extra_sections; 1981 1982 line_num = 0; 1983 readLine(); 1984 1985 while (readSuccess()) { 1986 skipSection(); 1987 try { 1988 char c; 1989 std::string section, caption; 1990 line >> c; 1991 _reader_bits::readToken(line, section); 1992 _reader_bits::readToken(line, caption); 1993 1994 if (line >> c) 1995 throw DataFormatError("Extra character on the end of line"); 1996 1997 if (section == "nodes" && !nodes_done) { 1998 if (_nodes_caption.empty() || _nodes_caption == caption) { 1999 readNodes(); 2000 nodes_done = true; 2001 } 2002 } else if ((section == "edges" || section == "arcs") && 2003 !edges_done) { 2004 if (_edges_caption.empty() || _edges_caption == caption) { 2005 readEdges(); 2006 edges_done = true; 2007 } 2008 } else if (section == "attributes" && !attributes_done) { 2009 if (_attributes_caption.empty() || _attributes_caption == caption) { 2010 readAttributes(); 2011 attributes_done = true; 2012 } 2013 } else { 2014 if (extra_sections.find(section) != extra_sections.end()) { 2015 std::ostringstream msg; 2016 msg << "Multiple occurence of section " << section; 2017 throw DataFormatError(msg.str().c_str()); 2018 } 2019 Sections::iterator it = _sections.find(section); 2020 if (it != _sections.end()) { 2021 extra_sections.insert(section); 2022 it->second->process(*_is, line_num); 2023 readLine(); 2024 } else { 2025 readLine(); 2026 skipSection(); 2027 } 2028 } 2029 } catch (DataFormatError& error) { 2030 error.line(line_num); 2031 throw; 2032 } 2033 } 2034 2035 if (!nodes_done) { 2036 throw DataFormatError("Section @nodes not found"); 2037 } 2038 2039 if (!edges_done) { 2040 throw DataFormatError("Section @edges not found"); 2041 } 2042 2043 if (!attributes_done && !_attributes.empty()) { 2044 throw DataFormatError("Section @attributes not found"); 2045 } 2046 2047 } 2048 2049 /// @} 2050 2051 }; 2052 2053 /// \relates GraphReader 2054 template <typename Graph> 2055 GraphReader<Graph> graphReader(std::istream& is, Graph& graph) { 2056 GraphReader<Graph> tmp(is, graph); 2057 return tmp; 2058 } 2059 2060 /// \relates GraphReader 2061 template <typename Graph> 2062 GraphReader<Graph> graphReader(const std::string& fn, 2063 Graph& graph) { 2064 GraphReader<Graph> tmp(fn, graph); 2065 return tmp; 2066 } 2067 2068 /// \relates GraphReader 2069 template <typename Graph> 2070 GraphReader<Graph> graphReader(const char* fn, Graph& graph) { 2071 GraphReader<Graph> tmp(fn, graph); 2072 return tmp; 2073 } 1183 2074 } 1184 2075 -
lemon/lgf_writer.h
r163 r165 72 72 }; 73 73 74 template <typename _Graph, bool _dir, typename _Map> 75 class GraphArcMapLess { 76 public: 77 typedef _Map Map; 78 typedef _Graph Graph; 79 typedef typename Graph::Edge Item; 80 81 private: 82 const Graph& _graph; 83 const Map& _map; 84 85 public: 86 GraphArcMapLess(const Graph& graph, const Map& map) 87 : _graph(graph), _map(map) {} 88 89 bool operator()(const Item& left, const Item& right) { 90 return _map[_graph.direct(left, _dir)] < 91 _map[_graph.direct(right, _dir)]; 92 } 93 }; 94 74 95 template <typename _Item> 75 96 class MapStorageBase { … … 107 128 virtual void sort(std::vector<Item>& items) { 108 129 MapLess<Map> less(_map); 130 std::sort(items.begin(), items.end(), less); 131 } 132 }; 133 134 template <typename _Graph, bool _dir, typename _Map, 135 typename _Converter = DefaultConverter<typename _Map::Value> > 136 class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> { 137 public: 138 typedef _Map Map; 139 typedef _Converter Converter; 140 typedef _Graph Graph; 141 typedef typename Graph::Edge Item; 142 static const bool dir = _dir; 143 144 private: 145 const Graph& _graph; 146 const Map& _map; 147 Converter _converter; 148 149 public: 150 GraphArcMapStorage(const Graph& graph, const Map& map, 151 const Converter& converter = Converter()) 152 : _graph(graph), _map(map), _converter(converter) {} 153 virtual ~GraphArcMapStorage() {} 154 155 virtual std::string get(const Item& item) { 156 return _converter(_map[_graph.direct(item, dir)]); 157 } 158 virtual void sort(std::vector<Item>& items) { 159 GraphArcMapLess<Graph, dir, Map> less(_graph, _map); 109 160 std::sort(items.begin(), items.end(), less); 110 161 } … … 152 203 } 153 204 return it->second; 205 } 206 }; 207 208 template <typename Graph> 209 struct GraphArcLookUpConverter { 210 const Graph& _graph; 211 const std::map<typename Graph::Edge, std::string>& _map; 212 213 GraphArcLookUpConverter(const Graph& graph, 214 const std::map<typename Graph::Edge, 215 std::string>& map) 216 : _graph(graph), _map(map) {} 217 218 std::string operator()(const typename Graph::Arc& val) { 219 typename std::map<typename Graph::Edge, std::string> 220 ::const_iterator it = _map.find(val); 221 if (it == _map.end()) { 222 throw DataFormatError("Item not found"); 223 } 224 return (_graph.direction(val) ? '+' : '-') + it->second; 154 225 } 155 226 }; … … 739 810 return tmp; 740 811 } 812 813 /// \ingroup lemon_io 814 /// 815 /// \brief LGF writer for directed graphs 816 /// 817 /// This utility writes an \ref lgf-format "LGF" file. 818 template <typename _Graph> 819 class GraphWriter { 820 public: 821 822 typedef _Graph Graph; 823 TEMPLATE_GRAPH_TYPEDEFS(Graph); 824 825 private: 826 827 828 std::ostream* _os; 829 bool local_os; 830 831 Graph& _graph; 832 833 std::string _nodes_caption; 834 std::string _edges_caption; 835 std::string _attributes_caption; 836 837 typedef std::map<Node, std::string> NodeIndex; 838 NodeIndex _node_index; 839 typedef std::map<Edge, std::string> EdgeIndex; 840 EdgeIndex _edge_index; 841 842 typedef std::vector<std::pair<std::string, 843 _writer_bits::MapStorageBase<Node>* > > NodeMaps; 844 NodeMaps _node_maps; 845 846 typedef std::vector<std::pair<std::string, 847 _writer_bits::MapStorageBase<Edge>* > >EdgeMaps; 848 EdgeMaps _edge_maps; 849 850 typedef std::vector<std::pair<std::string, 851 _writer_bits::ValueStorageBase*> > Attributes; 852 Attributes _attributes; 853 854 bool _skip_nodes; 855 bool _skip_edges; 856 857 public: 858 859 /// \brief Constructor 860 /// 861 /// Construct a directed graph writer, which writes to the given 862 /// output stream. 863 GraphWriter(std::ostream& is, Graph& graph) 864 : _os(&is), local_os(false), _graph(graph), 865 _skip_nodes(false), _skip_edges(false) {} 866 867 /// \brief Constructor 868 /// 869 /// Construct a directed graph writer, which writes to the given 870 /// output file. 871 GraphWriter(const std::string& fn, Graph& graph) 872 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph), 873 _skip_nodes(false), _skip_edges(false) {} 874 875 /// \brief Constructor 876 /// 877 /// Construct a directed graph writer, which writes to the given 878 /// output file. 879 GraphWriter(const char* fn, Graph& graph) 880 : _os(new std::ofstream(fn)), local_os(true), _graph(graph), 881 _skip_nodes(false), _skip_edges(false) {} 882 883 /// \brief Copy constructor 884 /// 885 /// The copy constructor transfers all data from the other writer, 886 /// therefore the copied writer will not be usable more. 887 GraphWriter(GraphWriter& other) 888 : _os(other._os), local_os(other.local_os), _graph(other._graph), 889 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) { 890 891 other._os = 0; 892 other.local_os = false; 893 894 _node_index.swap(other._node_index); 895 _edge_index.swap(other._edge_index); 896 897 _node_maps.swap(other._node_maps); 898 _edge_maps.swap(other._edge_maps); 899 _attributes.swap(other._attributes); 900 901 _nodes_caption = other._nodes_caption; 902 _edges_caption = other._edges_caption; 903 _attributes_caption = other._attributes_caption; 904 } 905 906 /// \brief Destructor 907 ~GraphWriter() { 908 for (typename NodeMaps::iterator it = _node_maps.begin(); 909 it != _node_maps.end(); ++it) { 910 delete it->second; 911 } 912 913 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 914 it != _edge_maps.end(); ++it) { 915 delete it->second; 916 } 917 918 for (typename Attributes::iterator it = _attributes.begin(); 919 it != _attributes.end(); ++it) { 920 delete it->second; 921 } 922 923 if (local_os) { 924 delete _os; 925 } 926 } 927 928 private: 929 930 GraphWriter& operator=(const GraphWriter&); 931 932 public: 933 934 /// \name Writing rules 935 /// @{ 936 937 /// \brief Node map reading rule 938 /// 939 /// Add a node map reading rule to the writer. 940 template <typename Map> 941 GraphWriter& nodeMap(const std::string& caption, const Map& map) { 942 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 943 _writer_bits::MapStorageBase<Node>* storage = 944 new _writer_bits::MapStorage<Node, Map>(map); 945 _node_maps.push_back(std::make_pair(caption, storage)); 946 return *this; 947 } 948 949 /// \brief Node map writing rule 950 /// 951 /// Add a node map writing rule with specialized converter to the 952 /// writer. 953 template <typename Map, typename Converter> 954 GraphWriter& nodeMap(const std::string& caption, const Map& map, 955 const Converter& converter = Converter()) { 956 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 957 _writer_bits::MapStorageBase<Node>* storage = 958 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); 959 _node_maps.push_back(std::make_pair(caption, storage)); 960 return *this; 961 } 962 963 /// \brief Edge map writing rule 964 /// 965 /// Add an edge map writing rule to the writer. 966 template <typename Map> 967 GraphWriter& edgeMap(const std::string& caption, const Map& map) { 968 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 969 _writer_bits::MapStorageBase<Edge>* storage = 970 new _writer_bits::MapStorage<Edge, Map>(map); 971 _edge_maps.push_back(std::make_pair(caption, storage)); 972 return *this; 973 } 974 975 /// \brief Edge map writing rule 976 /// 977 /// Add an edge map writing rule with specialized converter to the 978 /// writer. 979 template <typename Map, typename Converter> 980 GraphWriter& edgeMap(const std::string& caption, const Map& map, 981 const Converter& converter = Converter()) { 982 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 983 _writer_bits::MapStorageBase<Edge>* storage = 984 new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter); 985 _edge_maps.push_back(std::make_pair(caption, storage)); 986 return *this; 987 } 988 989 /// \brief Arc map writing rule 990 /// 991 /// Add an arc map writing rule to the writer. 992 template <typename Map> 993 GraphWriter& arcMap(const std::string& caption, const Map& map) { 994 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); 995 _writer_bits::MapStorageBase<Edge>* forward_storage = 996 new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map); 997 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 998 _writer_bits::MapStorageBase<Edge>* backward_storage = 999 new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map); 1000 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 1001 return *this; 1002 } 1003 1004 /// \brief Arc map writing rule 1005 /// 1006 /// Add an arc map writing rule with specialized converter to the 1007 /// writer. 1008 template <typename Map, typename Converter> 1009 GraphWriter& arcMap(const std::string& caption, const Map& map, 1010 const Converter& converter = Converter()) { 1011 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); 1012 _writer_bits::MapStorageBase<Edge>* forward_storage = 1013 new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter> 1014 (_graph, map, converter); 1015 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 1016 _writer_bits::MapStorageBase<Edge>* backward_storage = 1017 new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter> 1018 (_graph, map, converter); 1019 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 1020 return *this; 1021 } 1022 1023 /// \brief Attribute writing rule 1024 /// 1025 /// Add an attribute writing rule to the writer. 1026 template <typename Value> 1027 GraphWriter& attribute(const std::string& caption, const Value& value) { 1028 _writer_bits::ValueStorageBase* storage = 1029 new _writer_bits::ValueStorage<Value>(value); 1030 _attributes.push_back(std::make_pair(caption, storage)); 1031 return *this; 1032 } 1033 1034 /// \brief Attribute writing rule 1035 /// 1036 /// Add an attribute writing rule with specialized converter to the 1037 /// writer. 1038 template <typename Value, typename Converter> 1039 GraphWriter& attribute(const std::string& caption, const Value& value, 1040 const Converter& converter = Converter()) { 1041 _writer_bits::ValueStorageBase* storage = 1042 new _writer_bits::ValueStorage<Value, Converter>(value, converter); 1043 _attributes.push_back(std::make_pair(caption, storage)); 1044 return *this; 1045 } 1046 1047 /// \brief Node writing rule 1048 /// 1049 /// Add a node writing rule to the writer. 1050 GraphWriter& node(const std::string& caption, const Node& node) { 1051 typedef _writer_bits::MapLookUpConverter<Node> Converter; 1052 Converter converter(_node_index); 1053 _writer_bits::ValueStorageBase* storage = 1054 new _writer_bits::ValueStorage<Node, Converter>(node, converter); 1055 _attributes.push_back(std::make_pair(caption, storage)); 1056 return *this; 1057 } 1058 1059 /// \brief Edge writing rule 1060 /// 1061 /// Add an edge writing rule to writer. 1062 GraphWriter& edge(const std::string& caption, const Edge& edge) { 1063 typedef _writer_bits::MapLookUpConverter<Edge> Converter; 1064 Converter converter(_edge_index); 1065 _writer_bits::ValueStorageBase* storage = 1066 new _writer_bits::ValueStorage<Edge, Converter>(edge, converter); 1067 _attributes.push_back(std::make_pair(caption, storage)); 1068 return *this; 1069 } 1070 1071 /// \brief Arc writing rule 1072 /// 1073 /// Add an arc writing rule to writer. 1074 GraphWriter& arc(const std::string& caption, const Arc& arc) { 1075 typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter; 1076 Converter converter(_graph, _edge_index); 1077 _writer_bits::ValueStorageBase* storage = 1078 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter); 1079 _attributes.push_back(std::make_pair(caption, storage)); 1080 return *this; 1081 } 1082 1083 /// \name Select section by name 1084 /// @{ 1085 1086 /// \brief Set \c \@nodes section to be read 1087 /// 1088 /// Set \c \@nodes section to be read 1089 GraphWriter& nodes(const std::string& caption) { 1090 _nodes_caption = caption; 1091 return *this; 1092 } 1093 1094 /// \brief Set \c \@edges section to be read 1095 /// 1096 /// Set \c \@edges section to be read 1097 GraphWriter& edges(const std::string& caption) { 1098 _edges_caption = caption; 1099 return *this; 1100 } 1101 1102 /// \brief Set \c \@attributes section to be read 1103 /// 1104 /// Set \c \@attributes section to be read 1105 GraphWriter& attributes(const std::string& caption) { 1106 _attributes_caption = caption; 1107 return *this; 1108 } 1109 1110 /// \name Skipping section 1111 /// @{ 1112 1113 /// \brief Skip writing the node set 1114 /// 1115 /// The \c \@nodes section will be not written to the stream. 1116 GraphWriter& skipNodes() { 1117 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member"); 1118 return *this; 1119 } 1120 1121 /// \brief Skip writing edge set 1122 /// 1123 /// The \c \@edges section will be not written to the stream. 1124 GraphWriter& skipEdges() { 1125 LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member"); 1126 return *this; 1127 } 1128 1129 /// @} 1130 1131 private: 1132 1133 void writeNodes() { 1134 _writer_bits::MapStorageBase<Node>* label = 0; 1135 for (typename NodeMaps::iterator it = _node_maps.begin(); 1136 it != _node_maps.end(); ++it) { 1137 if (it->first == "label") { 1138 label = it->second; 1139 break; 1140 } 1141 } 1142 1143 *_os << "@nodes"; 1144 if (!_nodes_caption.empty()) { 1145 _writer_bits::writeToken(*_os << ' ', _nodes_caption); 1146 } 1147 *_os << std::endl; 1148 1149 if (label == 0) { 1150 *_os << "label" << '\t'; 1151 } 1152 for (typename NodeMaps::iterator it = _node_maps.begin(); 1153 it != _node_maps.end(); ++it) { 1154 _writer_bits::writeToken(*_os, it->first) << '\t'; 1155 } 1156 *_os << std::endl; 1157 1158 std::vector<Node> nodes; 1159 for (NodeIt n(_graph); n != INVALID; ++n) { 1160 nodes.push_back(n); 1161 } 1162 1163 if (label == 0) { 1164 IdMap<Graph, Node> id_map(_graph); 1165 _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map); 1166 std::sort(nodes.begin(), nodes.end(), id_less); 1167 } else { 1168 label->sort(nodes); 1169 } 1170 1171 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { 1172 Node n = nodes[i]; 1173 if (label == 0) { 1174 std::ostringstream os; 1175 os << _graph.id(n); 1176 _writer_bits::writeToken(*_os, os.str()); 1177 *_os << '\t'; 1178 _node_index.insert(std::make_pair(n, os.str())); 1179 } 1180 for (typename NodeMaps::iterator it = _node_maps.begin(); 1181 it != _node_maps.end(); ++it) { 1182 std::string value = it->second->get(n); 1183 _writer_bits::writeToken(*_os, value); 1184 if (it->first == "label") { 1185 _node_index.insert(std::make_pair(n, value)); 1186 } 1187 *_os << '\t'; 1188 } 1189 *_os << std::endl; 1190 } 1191 } 1192 1193 void writeEdges() { 1194 _writer_bits::MapStorageBase<Edge>* label = 0; 1195 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 1196 it != _edge_maps.end(); ++it) { 1197 if (it->first == "label") { 1198 label = it->second; 1199 break; 1200 } 1201 } 1202 1203 *_os << "@edges"; 1204 if (!_edges_caption.empty()) { 1205 _writer_bits::writeToken(*_os << ' ', _edges_caption); 1206 } 1207 *_os << std::endl; 1208 1209 *_os << '\t' << '\t'; 1210 if (label == 0) { 1211 *_os << "label" << '\t'; 1212 } 1213 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 1214 it != _edge_maps.end(); ++it) { 1215 _writer_bits::writeToken(*_os, it->first) << '\t'; 1216 } 1217 *_os << std::endl; 1218 1219 std::vector<Edge> edges; 1220 for (EdgeIt n(_graph); n != INVALID; ++n) { 1221 edges.push_back(n); 1222 } 1223 1224 if (label == 0) { 1225 IdMap<Graph, Edge> id_map(_graph); 1226 _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map); 1227 std::sort(edges.begin(), edges.end(), id_less); 1228 } else { 1229 label->sort(edges); 1230 } 1231 1232 for (int i = 0; i < static_cast<int>(edges.size()); ++i) { 1233 Edge e = edges[i]; 1234 _writer_bits::writeToken(*_os, _node_index. 1235 find(_graph.u(e))->second); 1236 *_os << '\t'; 1237 _writer_bits::writeToken(*_os, _node_index. 1238 find(_graph.v(e))->second); 1239 *_os << '\t'; 1240 if (label == 0) { 1241 std::ostringstream os; 1242 os << _graph.id(e); 1243 _writer_bits::writeToken(*_os, os.str()); 1244 *_os << '\t'; 1245 _edge_index.insert(std::make_pair(e, os.str())); 1246 } 1247 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 1248 it != _edge_maps.end(); ++it) { 1249 std::string value = it->second->get(e); 1250 _writer_bits::writeToken(*_os, value); 1251 if (it->first == "label") { 1252 _edge_index.insert(std::make_pair(e, value)); 1253 } 1254 *_os << '\t'; 1255 } 1256 *_os << std::endl; 1257 } 1258 } 1259 1260 void writeAttributes() { 1261 if (_attributes.empty()) return; 1262 *_os << "@attributes"; 1263 if (!_attributes_caption.empty()) { 1264 _writer_bits::writeToken(*_os << ' ', _attributes_caption); 1265 } 1266 *_os << std::endl; 1267 for (typename Attributes::iterator it = _attributes.begin(); 1268 it != _attributes.end(); ++it) { 1269 _writer_bits::writeToken(*_os, it->first) << ' '; 1270 _writer_bits::writeToken(*_os, it->second->get()); 1271 *_os << std::endl; 1272 } 1273 } 1274 1275 public: 1276 1277 /// \name Execution of the writer 1278 /// @{ 1279 1280 /// \brief Start the batch processing 1281 /// 1282 /// This function starts the batch processing 1283 void run() { 1284 if (!_skip_nodes) { 1285 writeNodes(); 1286 } 1287 if (!_skip_edges) { 1288 writeEdges(); 1289 } 1290 writeAttributes(); 1291 } 1292 1293 /// \brief Gives back the stream of the writer 1294 /// 1295 /// Gives back the stream of the writer 1296 std::ostream& ostream() { 1297 return *_os; 1298 } 1299 1300 /// @} 1301 }; 1302 1303 /// \relates GraphWriter 1304 template <typename Graph> 1305 GraphWriter<Graph> graphWriter(std::ostream& os, Graph& graph) { 1306 GraphWriter<Graph> tmp(os, graph); 1307 return tmp; 1308 } 1309 1310 /// \relates GraphWriter 1311 template <typename Graph> 1312 GraphWriter<Graph> graphWriter(const std::string& fn, Graph& graph) { 1313 GraphWriter<Graph> tmp(fn, graph); 1314 return tmp; 1315 } 1316 1317 /// \relates GraphWriter 1318 template <typename Graph> 1319 GraphWriter<Graph> graphWriter(const char* fn, Graph& graph) { 1320 GraphWriter<Graph> tmp(fn, graph); 1321 return tmp; 1322 } 741 1323 } 742 1324
Note: See TracChangeset
for help on using the changeset viewer.