# HG changeset patch # User Balazs Dezso # Date 1360649752 -3600 # Node ID 4936be66d2f554400c570e36a2e1a21077a1bbb2 # Parent 374a9519986b274b10f5a5abea11825c21b87128 Changes in BpGraph lgf reader and writer (#69) - Add typesade RedNode and BlueNode reading and writing - RedNodes and BlueNodes don't need to have distinct label set - Add tests diff -r 374a9519986b -r 4936be66d2f5 lemon/lgf_reader.h --- a/lemon/lgf_reader.h Sun Feb 05 00:04:44 2012 +0100 +++ b/lemon/lgf_reader.h Tue Feb 12 07:15:52 2013 +0100 @@ -154,16 +154,16 @@ } }; - template + template > struct MapLookUpConverter { - const std::map& _map; - - MapLookUpConverter(const std::map& map) + const Map& _map; + + MapLookUpConverter(const Map& map) : _map(map) {} Value operator()(const std::string& str) { - typename std::map::const_iterator it = - _map.find(str); + typename Map::const_iterator it = _map.find(str); if (it == _map.end()) { std::ostringstream msg; msg << "Item not found: " << str; @@ -173,6 +173,39 @@ } }; + template , + typename Map2 = std::map > + struct DoubleMapLookUpConverter { + const Map1& _map1; + const Map2& _map2; + + DoubleMapLookUpConverter(const Map1& map1, const Map2& map2) + : _map1(map1), _map2(map2) {} + + Value operator()(const std::string& str) { + typename Map1::const_iterator it1 = _map1.find(str); + typename Map2::const_iterator it2 = _map2.find(str); + if (it1 == _map1.end()) { + if (it2 == _map2.end()) { + std::ostringstream msg; + msg << "Item not found: " << str; + throw FormatError(msg.str()); + } else { + return it2->second; + } + } else { + if (it2 == _map2.end()) { + return it1->second; + } else { + std::ostringstream msg; + msg << "Item is ambigous: " << str; + throw FormatError(msg.str()); + } + } + } + }; + template struct GraphArcLookUpConverter { const GR& _graph; @@ -2171,15 +2204,19 @@ std::string _edges_caption; std::string _attributes_caption; - typedef std::map NodeIndex; - NodeIndex _node_index; + typedef std::map RedNodeIndex; + RedNodeIndex _red_node_index; + typedef std::map BlueNodeIndex; + BlueNodeIndex _blue_node_index; typedef std::map EdgeIndex; EdgeIndex _edge_index; typedef std::vector*> > NodeMaps; - NodeMaps _red_maps; - NodeMaps _blue_maps; + _reader_bits::MapStorageBase*> > RedNodeMaps; + RedNodeMaps _red_node_maps; + typedef std::vector*> > BlueNodeMaps; + BlueNodeMaps _blue_node_maps; typedef std::vector*> > EdgeMaps; @@ -2241,13 +2278,13 @@ /// \brief Destructor ~BpGraphReader() { - for (typename NodeMaps::iterator it = _red_maps.begin(); - it != _red_maps.end(); ++it) { + for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); + it != _red_node_maps.end(); ++it) { delete it->second; } - for (typename NodeMaps::iterator it = _blue_maps.begin(); - it != _blue_maps.end(); ++it) { + for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); + it != _blue_node_maps.end(); ++it) { delete it->second; } @@ -2284,11 +2321,12 @@ other._is = 0; other.local_is = false; - _node_index.swap(other._node_index); + _red_node_index.swap(other._red_node_index); + _blue_node_index.swap(other._blue_node_index); _edge_index.swap(other._edge_index); - _red_maps.swap(other._red_maps); - _blue_maps.swap(other._blue_maps); + _red_node_maps.swap(other._red_node_maps); + _blue_node_maps.swap(other._blue_node_maps); _edge_maps.swap(other._edge_maps); _attributes.swap(other._attributes); @@ -2311,12 +2349,12 @@ template BpGraphReader& nodeMap(const std::string& caption, Map& map) { checkConcept, Map>(); - _reader_bits::MapStorageBase* red_storage = - new _reader_bits::MapStorage(map); - _red_maps.push_back(std::make_pair(caption, red_storage)); - _reader_bits::MapStorageBase* blue_storage = - new _reader_bits::MapStorage(map); - _blue_maps.push_back(std::make_pair(caption, blue_storage)); + _reader_bits::MapStorageBase* red_storage = + new _reader_bits::MapStorage(map); + _red_node_maps.push_back(std::make_pair(caption, red_storage)); + _reader_bits::MapStorageBase* blue_storage = + new _reader_bits::MapStorage(map); + _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); return *this; } @@ -2328,22 +2366,22 @@ BpGraphReader& nodeMap(const std::string& caption, Map& map, const Converter& converter = Converter()) { checkConcept, Map>(); - _reader_bits::MapStorageBase* red_storage = - new _reader_bits::MapStorage(map, converter); - _red_maps.push_back(std::make_pair(caption, red_storage)); - _reader_bits::MapStorageBase* blue_storage = - new _reader_bits::MapStorage(map, converter); - _blue_maps.push_back(std::make_pair(caption, blue_storage)); + _reader_bits::MapStorageBase* red_storage = + new _reader_bits::MapStorage(map, converter); + _red_node_maps.push_back(std::make_pair(caption, red_storage)); + _reader_bits::MapStorageBase* blue_storage = + new _reader_bits::MapStorage(map, converter); + _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); return *this; } /// Add a red node map reading rule to the reader. template BpGraphReader& redNodeMap(const std::string& caption, Map& map) { - checkConcept, Map>(); - _reader_bits::MapStorageBase* storage = - new _reader_bits::MapStorage(map); - _red_maps.push_back(std::make_pair(caption, storage)); + checkConcept, Map>(); + _reader_bits::MapStorageBase* storage = + new _reader_bits::MapStorage(map); + _red_node_maps.push_back(std::make_pair(caption, storage)); return *this; } @@ -2354,20 +2392,20 @@ template BpGraphReader& redNodeMap(const std::string& caption, Map& map, const Converter& converter = Converter()) { - checkConcept, Map>(); - _reader_bits::MapStorageBase* storage = - new _reader_bits::MapStorage(map, converter); - _red_maps.push_back(std::make_pair(caption, storage)); + checkConcept, Map>(); + _reader_bits::MapStorageBase* storage = + new _reader_bits::MapStorage(map, converter); + _red_node_maps.push_back(std::make_pair(caption, storage)); return *this; } /// Add a blue node map reading rule to the reader. template BpGraphReader& blueNodeMap(const std::string& caption, Map& map) { - checkConcept, Map>(); - _reader_bits::MapStorageBase* storage = - new _reader_bits::MapStorage(map); - _blue_maps.push_back(std::make_pair(caption, storage)); + checkConcept, Map>(); + _reader_bits::MapStorageBase* storage = + new _reader_bits::MapStorage(map); + _blue_node_maps.push_back(std::make_pair(caption, storage)); return *this; } @@ -2378,10 +2416,10 @@ template BpGraphReader& blueNodeMap(const std::string& caption, Map& map, const Converter& converter = Converter()) { - checkConcept, Map>(); - _reader_bits::MapStorageBase* storage = - new _reader_bits::MapStorage(map, converter); - _blue_maps.push_back(std::make_pair(caption, storage)); + checkConcept, Map>(); + _reader_bits::MapStorageBase* storage = + new _reader_bits::MapStorage(map, converter); + _blue_node_maps.push_back(std::make_pair(caption, storage)); return *this; } @@ -2473,14 +2511,39 @@ /// /// Add a node reading rule to reader. BpGraphReader& node(const std::string& caption, Node& node) { - typedef _reader_bits::MapLookUpConverter Converter; - Converter converter(_node_index); + typedef _reader_bits::DoubleMapLookUpConverter< + Node, RedNodeIndex, BlueNodeIndex> Converter; + Converter converter(_red_node_index, _blue_node_index); _reader_bits::ValueStorageBase* storage = new _reader_bits::ValueStorage(node, converter); _attributes.insert(std::make_pair(caption, storage)); return *this; } + /// \brief Red node reading rule + /// + /// Add a red node reading rule to reader. + BpGraphReader& redNode(const std::string& caption, RedNode& node) { + typedef _reader_bits::MapLookUpConverter Converter; + Converter converter(_red_node_index); + _reader_bits::ValueStorageBase* storage = + new _reader_bits::ValueStorage(node, converter); + _attributes.insert(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Blue node reading rule + /// + /// Add a blue node reading rule to reader. + BpGraphReader& blueNode(const std::string& caption, BlueNode& node) { + typedef _reader_bits::MapLookUpConverter Converter; + Converter converter(_blue_node_index); + _reader_bits::ValueStorageBase* storage = + new _reader_bits::ValueStorage(node, converter); + _attributes.insert(std::make_pair(caption, storage)); + return *this; + } + /// \brief Edge reading rule /// /// Add an edge reading rule to reader. @@ -2549,8 +2612,11 @@ LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); _use_nodes = true; _writer_bits::DefaultConverter converter; - for (NodeIt n(_graph); n != INVALID; ++n) { - _node_index.insert(std::make_pair(converter(map[n]), n)); + for (RedNodeIt n(_graph); n != INVALID; ++n) { + _red_node_index.insert(std::make_pair(converter(map[n]), n)); + } + for (BlueNodeIt n(_graph); n != INVALID; ++n) { + _blue_node_index.insert(std::make_pair(converter(map[n]), n)); } return *this; } @@ -2566,8 +2632,11 @@ checkConcept, Map>(); LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); _use_nodes = true; - for (NodeIt n(_graph); n != INVALID; ++n) { - _node_index.insert(std::make_pair(converter(map[n]), n)); + for (RedNodeIt n(_graph); n != INVALID; ++n) { + _red_node_index.insert(std::make_pair(converter(map[n]), n)); + } + for (BlueNodeIt n(_graph); n != INVALID; ++n) { + _blue_node_index.insert(std::make_pair(converter(map[n]), n)); } return *this; } @@ -2664,13 +2733,13 @@ void readRedNodes() { - std::vector map_index(_red_maps.size()); + std::vector map_index(_red_node_maps.size()); int map_num, label_index; char c; if (!readLine() || !(line >> c) || c == '@') { if (readSuccess() && line) line.putback(c); - if (!_red_maps.empty()) + if (!_red_node_maps.empty()) throw FormatError("Cannot find map names"); return; } @@ -2691,12 +2760,12 @@ ++index; } - for (int i = 0; i < static_cast(_red_maps.size()); ++i) { + for (int i = 0; i < static_cast(_red_node_maps.size()); ++i) { std::map::iterator jt = - maps.find(_red_maps[i].first); + maps.find(_red_node_maps[i].first); if (jt == maps.end()) { std::ostringstream msg; - msg << "Map not found: " << _red_maps[i].first; + msg << "Map not found: " << _red_node_maps[i].first; throw FormatError(msg.str()); } map_index[i] = jt->second; @@ -2727,17 +2796,17 @@ if (line >> std::ws >> c) throw FormatError("Extra character at the end of line"); - Node n; + RedNode n; if (!_use_nodes) { n = _graph.addRedNode(); if (label_index != -1) - _node_index.insert(std::make_pair(tokens[label_index], n)); + _red_node_index.insert(std::make_pair(tokens[label_index], n)); } else { if (label_index == -1) throw FormatError("Label map not found"); - typename std::map::iterator it = - _node_index.find(tokens[label_index]); - if (it == _node_index.end()) { + typename std::map::iterator it = + _red_node_index.find(tokens[label_index]); + if (it == _red_node_index.end()) { std::ostringstream msg; msg << "Node with label not found: " << tokens[label_index]; throw FormatError(msg.str()); @@ -2745,8 +2814,8 @@ n = it->second; } - for (int i = 0; i < static_cast(_red_maps.size()); ++i) { - _red_maps[i].second->set(n, tokens[map_index[i]]); + for (int i = 0; i < static_cast(_red_node_maps.size()); ++i) { + _red_node_maps[i].second->set(n, tokens[map_index[i]]); } } @@ -2757,13 +2826,13 @@ void readBlueNodes() { - std::vector map_index(_blue_maps.size()); + std::vector map_index(_blue_node_maps.size()); int map_num, label_index; char c; if (!readLine() || !(line >> c) || c == '@') { if (readSuccess() && line) line.putback(c); - if (!_blue_maps.empty()) + if (!_blue_node_maps.empty()) throw FormatError("Cannot find map names"); return; } @@ -2784,12 +2853,12 @@ ++index; } - for (int i = 0; i < static_cast(_blue_maps.size()); ++i) { + for (int i = 0; i < static_cast(_blue_node_maps.size()); ++i) { std::map::iterator jt = - maps.find(_blue_maps[i].first); + maps.find(_blue_node_maps[i].first); if (jt == maps.end()) { std::ostringstream msg; - msg << "Map not found: " << _blue_maps[i].first; + msg << "Map not found: " << _blue_node_maps[i].first; throw FormatError(msg.str()); } map_index[i] = jt->second; @@ -2820,17 +2889,17 @@ if (line >> std::ws >> c) throw FormatError("Extra character at the end of line"); - Node n; + BlueNode n; if (!_use_nodes) { n = _graph.addBlueNode(); if (label_index != -1) - _node_index.insert(std::make_pair(tokens[label_index], n)); + _blue_node_index.insert(std::make_pair(tokens[label_index], n)); } else { if (label_index == -1) throw FormatError("Label map not found"); - typename std::map::iterator it = - _node_index.find(tokens[label_index]); - if (it == _node_index.end()) { + typename std::map::iterator it = + _blue_node_index.find(tokens[label_index]); + if (it == _blue_node_index.end()) { std::ostringstream msg; msg << "Node with label not found: " << tokens[label_index]; throw FormatError(msg.str()); @@ -2838,8 +2907,8 @@ n = it->second; } - for (int i = 0; i < static_cast(_blue_maps.size()); ++i) { - _blue_maps[i].second->set(n, tokens[map_index[i]]); + for (int i = 0; i < static_cast(_blue_node_maps.size()); ++i) { + _blue_node_maps[i].second->set(n, tokens[map_index[i]]); } } @@ -2924,39 +2993,26 @@ Edge e; if (!_use_edges) { - - typename NodeIndex::iterator it; - - it = _node_index.find(source_token); - if (it == _node_index.end()) { + typename RedNodeIndex::iterator rit = + _red_node_index.find(source_token); + if (rit == _red_node_index.end()) { std::ostringstream msg; msg << "Item not found: " << source_token; throw FormatError(msg.str()); } - Node source = it->second; - if (!_graph.red(source)) { - std::ostringstream msg; - msg << "Item is not red node: " << source_token; - throw FormatError(msg.str()); - } - - it = _node_index.find(target_token); - if (it == _node_index.end()) { + RedNode source = rit->second; + typename BlueNodeIndex::iterator it = + _blue_node_index.find(target_token); + if (it == _blue_node_index.end()) { std::ostringstream msg; msg << "Item not found: " << target_token; throw FormatError(msg.str()); } - Node target = it->second; - if (!_graph.blue(target)) { - std::ostringstream msg; - msg << "Item is not red node: " << source_token; - throw FormatError(msg.str()); - } + BlueNode target = it->second; // It is checked that source is red and // target is blue, so this should be safe: - e = _graph.addEdge(_graph.asRedNodeUnsafe(source), - _graph.asBlueNodeUnsafe(target)); + e = _graph.addEdge(source, target); if (label_index != -1) _edge_index.insert(std::make_pair(tokens[label_index], e)); } else { diff -r 374a9519986b -r 4936be66d2f5 lemon/lgf_writer.h --- a/lemon/lgf_writer.h Sun Feb 05 00:04:44 2012 +0100 +++ b/lemon/lgf_writer.h Tue Feb 12 07:15:52 2013 +0100 @@ -185,22 +185,22 @@ public: ValueStorage(const Value& value, const Converter& converter = Converter()) : _value(value), _converter(converter) {} - + virtual std::string get() { return _converter(_value); } }; - template + template > struct MapLookUpConverter { - const std::map& _map; + const Map& _map; - MapLookUpConverter(const std::map& map) + MapLookUpConverter(const Map& map) : _map(map) {} - std::string operator()(const Value& str) { - typename std::map::const_iterator it = - _map.find(str); + std::string operator()(const Value& value) { + typename Map::const_iterator it = _map.find(value); if (it == _map.end()) { throw FormatError("Item not found"); } @@ -208,6 +208,35 @@ } }; + template , + typename Map2 = std::map > + struct DoubleMapLookUpConverter { + const Map1& _map1; + const Map2& _map2; + + DoubleMapLookUpConverter(const Map1& map1, const Map2& map2) + : _map1(map1), _map2(map2) {} + + std::string operator()(const Value& value) { + typename Map1::const_iterator it1 = _map1.find(value); + typename Map1::const_iterator it2 = _map2.find(value); + if (it1 == _map1.end()) { + if (it2 == _map2.end()) { + throw FormatError("Item not found"); + } else { + return it2->second; + } + } else { + if (it2 == _map2.end()) { + return it1->second; + } else { + throw FormatError("Item is ambigous"); + } + } + } + }; + template struct GraphArcLookUpConverter { const Graph& _graph; @@ -1651,15 +1680,19 @@ std::string _edges_caption; std::string _attributes_caption; - typedef std::map NodeIndex; - NodeIndex _node_index; + typedef std::map RedNodeIndex; + RedNodeIndex _red_node_index; + typedef std::map BlueNodeIndex; + BlueNodeIndex _blue_node_index; typedef std::map EdgeIndex; EdgeIndex _edge_index; typedef std::vector* > > NodeMaps; - NodeMaps _red_maps; - NodeMaps _blue_maps; + _writer_bits::MapStorageBase* > > RedNodeMaps; + RedNodeMaps _red_node_maps; + typedef std::vector* > > BlueNodeMaps; + BlueNodeMaps _blue_node_maps; typedef std::vector* > >EdgeMaps; @@ -1710,13 +1743,13 @@ /// \brief Destructor ~BpGraphWriter() { - for (typename NodeMaps::iterator it = _red_maps.begin(); - it != _red_maps.end(); ++it) { + for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); + it != _red_node_maps.end(); ++it) { delete it->second; } - for (typename NodeMaps::iterator it = _blue_maps.begin(); - it != _blue_maps.end(); ++it) { + for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); + it != _blue_node_maps.end(); ++it) { delete it->second; } @@ -1753,11 +1786,12 @@ other._os = 0; other.local_os = false; - _node_index.swap(other._node_index); + _red_node_index.swap(other._red_node_index); + _blue_node_index.swap(other._blue_node_index); _edge_index.swap(other._edge_index); - _red_maps.swap(other._red_maps); - _blue_maps.swap(other._blue_maps); + _red_node_maps.swap(other._red_node_maps); + _blue_node_maps.swap(other._blue_node_maps); _edge_maps.swap(other._edge_maps); _attributes.swap(other._attributes); @@ -1779,12 +1813,12 @@ template BpGraphWriter& nodeMap(const std::string& caption, const Map& map) { checkConcept, Map>(); - _writer_bits::MapStorageBase* red_storage = - new _writer_bits::MapStorage(map); - _red_maps.push_back(std::make_pair(caption, red_storage)); - _writer_bits::MapStorageBase* blue_storage = - new _writer_bits::MapStorage(map); - _blue_maps.push_back(std::make_pair(caption, blue_storage)); + _writer_bits::MapStorageBase* red_storage = + new _writer_bits::MapStorage(map); + _red_node_maps.push_back(std::make_pair(caption, red_storage)); + _writer_bits::MapStorageBase* blue_storage = + new _writer_bits::MapStorage(map); + _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); return *this; } @@ -1796,12 +1830,12 @@ BpGraphWriter& nodeMap(const std::string& caption, const Map& map, const Converter& converter = Converter()) { checkConcept, Map>(); - _writer_bits::MapStorageBase* red_storage = - new _writer_bits::MapStorage(map, converter); - _red_maps.push_back(std::make_pair(caption, red_storage)); - _writer_bits::MapStorageBase* blue_storage = - new _writer_bits::MapStorage(map, converter); - _blue_maps.push_back(std::make_pair(caption, blue_storage)); + _writer_bits::MapStorageBase* red_storage = + new _writer_bits::MapStorage(map, converter); + _red_node_maps.push_back(std::make_pair(caption, red_storage)); + _writer_bits::MapStorageBase* blue_storage = + new _writer_bits::MapStorage(map, converter); + _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); return *this; } @@ -1810,10 +1844,10 @@ /// Add a red node map writing rule to the writer. template BpGraphWriter& redNodeMap(const std::string& caption, const Map& map) { - checkConcept, Map>(); - _writer_bits::MapStorageBase* storage = - new _writer_bits::MapStorage(map); - _red_maps.push_back(std::make_pair(caption, storage)); + checkConcept, Map>(); + _writer_bits::MapStorageBase* storage = + new _writer_bits::MapStorage(map); + _red_node_maps.push_back(std::make_pair(caption, storage)); return *this; } @@ -1824,10 +1858,10 @@ template BpGraphWriter& redNodeMap(const std::string& caption, const Map& map, const Converter& converter = Converter()) { - checkConcept, Map>(); - _writer_bits::MapStorageBase* storage = - new _writer_bits::MapStorage(map, converter); - _red_maps.push_back(std::make_pair(caption, storage)); + checkConcept, Map>(); + _writer_bits::MapStorageBase* storage = + new _writer_bits::MapStorage(map, converter); + _red_node_maps.push_back(std::make_pair(caption, storage)); return *this; } @@ -1836,10 +1870,10 @@ /// Add a blue node map writing rule to the writer. template BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map) { - checkConcept, Map>(); - _writer_bits::MapStorageBase* storage = - new _writer_bits::MapStorage(map); - _blue_maps.push_back(std::make_pair(caption, storage)); + checkConcept, Map>(); + _writer_bits::MapStorageBase* storage = + new _writer_bits::MapStorage(map); + _blue_node_maps.push_back(std::make_pair(caption, storage)); return *this; } @@ -1850,10 +1884,10 @@ template BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map, const Converter& converter = Converter()) { - checkConcept, Map>(); - _writer_bits::MapStorageBase* storage = - new _writer_bits::MapStorage(map, converter); - _blue_maps.push_back(std::make_pair(caption, storage)); + checkConcept, Map>(); + _writer_bits::MapStorageBase* storage = + new _writer_bits::MapStorage(map, converter); + _blue_node_maps.push_back(std::make_pair(caption, storage)); return *this; } @@ -1945,8 +1979,33 @@ /// /// Add a node writing rule to the writer. BpGraphWriter& node(const std::string& caption, const Node& node) { + typedef _writer_bits::DoubleMapLookUpConverter< + Node, RedNodeIndex, BlueNodeIndex> Converter; + Converter converter(_red_node_index, _blue_node_index); + _writer_bits::ValueStorageBase* storage = + new _writer_bits::ValueStorage(node, converter); + _attributes.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Red node writing rule + /// + /// Add a red node writing rule to the writer. + BpGraphWriter& redNode(const std::string& caption, const RedNode& node) { typedef _writer_bits::MapLookUpConverter Converter; - Converter converter(_node_index); + Converter converter(_red_node_index); + _writer_bits::ValueStorageBase* storage = + new _writer_bits::ValueStorage(node, converter); + _attributes.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Blue node writing rule + /// + /// Add a blue node writing rule to the writer. + BpGraphWriter& blueNode(const std::string& caption, const BlueNode& node) { + typedef _writer_bits::MapLookUpConverter Converter; + Converter converter(_blue_node_index); _writer_bits::ValueStorageBase* storage = new _writer_bits::ValueStorage(node, converter); _attributes.push_back(std::make_pair(caption, storage)); @@ -2033,9 +2092,9 @@ private: void writeRedNodes() { - _writer_bits::MapStorageBase* label = 0; - for (typename NodeMaps::iterator it = _red_maps.begin(); - it != _red_maps.end(); ++it) { + _writer_bits::MapStorageBase* label = 0; + for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); + it != _red_node_maps.end(); ++it) { if (it->first == "label") { label = it->second; break; @@ -2051,13 +2110,13 @@ if (label == 0) { *_os << "label" << '\t'; } - for (typename NodeMaps::iterator it = _red_maps.begin(); - it != _red_maps.end(); ++it) { + for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); + it != _red_node_maps.end(); ++it) { _writer_bits::writeToken(*_os, it->first) << '\t'; } *_os << std::endl; - std::vector nodes; + std::vector nodes; for (RedNodeIt n(_graph); n != INVALID; ++n) { nodes.push_back(n); } @@ -2071,20 +2130,20 @@ } for (int i = 0; i < static_cast(nodes.size()); ++i) { - Node n = nodes[i]; + RedNode n = nodes[i]; if (label == 0) { std::ostringstream os; - os << _graph.id(n); + os << _graph.id(static_cast(n)); _writer_bits::writeToken(*_os, os.str()); *_os << '\t'; - _node_index.insert(std::make_pair(n, os.str())); + _red_node_index.insert(std::make_pair(n, os.str())); } - for (typename NodeMaps::iterator it = _red_maps.begin(); - it != _red_maps.end(); ++it) { + for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); + it != _red_node_maps.end(); ++it) { std::string value = it->second->get(n); _writer_bits::writeToken(*_os, value); if (it->first == "label") { - _node_index.insert(std::make_pair(n, value)); + _red_node_index.insert(std::make_pair(n, value)); } *_os << '\t'; } @@ -2093,9 +2152,9 @@ } void writeBlueNodes() { - _writer_bits::MapStorageBase* label = 0; - for (typename NodeMaps::iterator it = _blue_maps.begin(); - it != _blue_maps.end(); ++it) { + _writer_bits::MapStorageBase* label = 0; + for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); + it != _blue_node_maps.end(); ++it) { if (it->first == "label") { label = it->second; break; @@ -2111,13 +2170,13 @@ if (label == 0) { *_os << "label" << '\t'; } - for (typename NodeMaps::iterator it = _blue_maps.begin(); - it != _blue_maps.end(); ++it) { + for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); + it != _blue_node_maps.end(); ++it) { _writer_bits::writeToken(*_os, it->first) << '\t'; } *_os << std::endl; - std::vector nodes; + std::vector nodes; for (BlueNodeIt n(_graph); n != INVALID; ++n) { nodes.push_back(n); } @@ -2131,20 +2190,20 @@ } for (int i = 0; i < static_cast(nodes.size()); ++i) { - Node n = nodes[i]; + BlueNode n = nodes[i]; if (label == 0) { std::ostringstream os; - os << _graph.id(n); + os << _graph.id(static_cast(n)); _writer_bits::writeToken(*_os, os.str()); *_os << '\t'; - _node_index.insert(std::make_pair(n, os.str())); + _blue_node_index.insert(std::make_pair(n, os.str())); } - for (typename NodeMaps::iterator it = _blue_maps.begin(); - it != _blue_maps.end(); ++it) { + for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); + it != _blue_node_maps.end(); ++it) { std::string value = it->second->get(n); _writer_bits::writeToken(*_os, value); if (it->first == "label") { - _node_index.insert(std::make_pair(n, value)); + _blue_node_index.insert(std::make_pair(n, value)); } *_os << '\t'; } @@ -2153,9 +2212,9 @@ } void createRedNodeIndex() { - _writer_bits::MapStorageBase* label = 0; - for (typename NodeMaps::iterator it = _red_maps.begin(); - it != _red_maps.end(); ++it) { + _writer_bits::MapStorageBase* label = 0; + for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); + it != _red_node_maps.end(); ++it) { if (it->first == "label") { label = it->second; break; @@ -2163,23 +2222,23 @@ } if (label == 0) { - for (NodeIt n(_graph); n != INVALID; ++n) { + for (RedNodeIt n(_graph); n != INVALID; ++n) { std::ostringstream os; os << _graph.id(n); - _node_index.insert(std::make_pair(n, os.str())); + _red_node_index.insert(std::make_pair(n, os.str())); } } else { - for (NodeIt n(_graph); n != INVALID; ++n) { + for (RedNodeIt n(_graph); n != INVALID; ++n) { std::string value = label->get(n); - _node_index.insert(std::make_pair(n, value)); + _red_node_index.insert(std::make_pair(n, value)); } } } void createBlueNodeIndex() { - _writer_bits::MapStorageBase* label = 0; - for (typename NodeMaps::iterator it = _blue_maps.begin(); - it != _blue_maps.end(); ++it) { + _writer_bits::MapStorageBase* label = 0; + for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); + it != _blue_node_maps.end(); ++it) { if (it->first == "label") { label = it->second; break; @@ -2187,15 +2246,15 @@ } if (label == 0) { - for (NodeIt n(_graph); n != INVALID; ++n) { + for (BlueNodeIt n(_graph); n != INVALID; ++n) { std::ostringstream os; os << _graph.id(n); - _node_index.insert(std::make_pair(n, os.str())); + _blue_node_index.insert(std::make_pair(n, os.str())); } } else { - for (NodeIt n(_graph); n != INVALID; ++n) { + for (BlueNodeIt n(_graph); n != INVALID; ++n) { std::string value = label->get(n); - _node_index.insert(std::make_pair(n, value)); + _blue_node_index.insert(std::make_pair(n, value)); } } } @@ -2241,10 +2300,10 @@ for (int i = 0; i < static_cast(edges.size()); ++i) { Edge e = edges[i]; - _writer_bits::writeToken(*_os, _node_index. + _writer_bits::writeToken(*_os, _red_node_index. find(_graph.redNode(e))->second); *_os << '\t'; - _writer_bits::writeToken(*_os, _node_index. + _writer_bits::writeToken(*_os, _blue_node_index. find(_graph.blueNode(e))->second); *_os << '\t'; if (label == 0) { diff -r 374a9519986b -r 4936be66d2f5 test/CMakeLists.txt --- a/test/CMakeLists.txt Sun Feb 05 00:04:44 2012 +0100 +++ b/test/CMakeLists.txt Tue Feb 12 07:15:52 2013 +0100 @@ -35,6 +35,7 @@ hao_orlin_test heap_test kruskal_test + lgf_reader_writer_test lgf_test maps_test matching_test diff -r 374a9519986b -r 4936be66d2f5 test/lgf_reader_writer_test.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/lgf_reader_writer_test.cc Tue Feb 12 07:15:52 2013 +0100 @@ -0,0 +1,578 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "test_tools.h" + +struct ReaderConverter { + int operator()(const std::string& str) const { + return str.length(); + } +}; + +struct WriterConverter { + std::string operator()(int value) const { + return std::string(value, '*'); + } +}; + +void checkDigraphReaderCompile() { + typedef lemon::concepts::ExtendableDigraphComponent< + lemon::concepts::Digraph> Digraph; + Digraph digraph; + Digraph::NodeMap node_map(digraph); + Digraph::ArcMap arc_map(digraph); + Digraph::Node node; + Digraph::Arc arc; + int attr; + + lemon::DigraphReader reader(digraph, "filename"); + reader.nodeMap("node_map", node_map); + reader.nodeMap("node_map", node_map, ReaderConverter()); + reader.arcMap("arc_map", arc_map); + reader.arcMap("arc_map", arc_map, ReaderConverter()); + reader.attribute("attr", attr); + reader.attribute("attr", attr, ReaderConverter()); + reader.node("node", node); + reader.arc("arc", arc); + + reader.nodes("alt_nodes_caption"); + reader.arcs("alt_arcs_caption"); + reader.attributes("alt_attrs_caption"); + + reader.useNodes(node_map); + reader.useNodes(node_map, WriterConverter()); + reader.useArcs(arc_map); + reader.useArcs(arc_map, WriterConverter()); + + reader.skipNodes(); + reader.skipArcs(); + + reader.run(); + + lemon::DigraphReader reader2(digraph, std::cin); +} + +void checkDigraphWriterCompile() { + typedef lemon::concepts::Digraph Digraph; + Digraph digraph; + Digraph::NodeMap node_map(digraph); + Digraph::ArcMap arc_map(digraph); + Digraph::Node node; + Digraph::Arc arc; + int attr; + + lemon::DigraphWriter writer(digraph, "filename"); + writer.nodeMap("node_map", node_map); + writer.nodeMap("node_map", node_map, WriterConverter()); + writer.arcMap("arc_map", arc_map); + writer.arcMap("arc_map", arc_map, WriterConverter()); + writer.attribute("attr", attr); + writer.attribute("attr", attr, WriterConverter()); + writer.node("node", node); + writer.arc("arc", arc); + + writer.nodes("alt_nodes_caption"); + writer.arcs("alt_arcs_caption"); + writer.attributes("alt_attrs_caption"); + + writer.skipNodes(); + writer.skipArcs(); + + writer.run(); +} + +void checkGraphReaderCompile() { + typedef lemon::concepts::ExtendableGraphComponent< + lemon::concepts::Graph> Graph; + Graph graph; + Graph::NodeMap node_map(graph); + Graph::ArcMap arc_map(graph); + Graph::EdgeMap edge_map(graph); + Graph::Node node; + Graph::Arc arc; + Graph::Edge edge; + int attr; + + lemon::GraphReader reader(graph, "filename"); + reader.nodeMap("node_map", node_map); + reader.nodeMap("node_map", node_map, ReaderConverter()); + reader.arcMap("arc_map", arc_map); + reader.arcMap("arc_map", arc_map, ReaderConverter()); + reader.edgeMap("edge_map", edge_map); + reader.edgeMap("edge_map", edge_map, ReaderConverter()); + reader.attribute("attr", attr); + reader.attribute("attr", attr, ReaderConverter()); + reader.node("node", node); + reader.arc("arc", arc); + + reader.nodes("alt_nodes_caption"); + reader.edges("alt_edges_caption"); + reader.attributes("alt_attrs_caption"); + + reader.useNodes(node_map); + reader.useNodes(node_map, WriterConverter()); + reader.useEdges(edge_map); + reader.useEdges(edge_map, WriterConverter()); + + reader.skipNodes(); + reader.skipEdges(); + + reader.run(); + + lemon::GraphReader reader2(graph, std::cin); +} + +void checkGraphWriterCompile() { + typedef lemon::concepts::Graph Graph; + Graph graph; + Graph::NodeMap node_map(graph); + Graph::ArcMap arc_map(graph); + Graph::EdgeMap edge_map(graph); + Graph::Node node; + Graph::Arc arc; + Graph::Edge edge; + int attr; + + lemon::GraphWriter writer(graph, "filename"); + writer.nodeMap("node_map", node_map); + writer.nodeMap("node_map", node_map, WriterConverter()); + writer.arcMap("arc_map", arc_map); + writer.arcMap("arc_map", arc_map, WriterConverter()); + writer.edgeMap("edge_map", edge_map); + writer.edgeMap("edge_map", edge_map, WriterConverter()); + writer.attribute("attr", attr); + writer.attribute("attr", attr, WriterConverter()); + writer.node("node", node); + writer.arc("arc", arc); + writer.edge("edge", edge); + + writer.nodes("alt_nodes_caption"); + writer.edges("alt_edges_caption"); + writer.attributes("alt_attrs_caption"); + + writer.skipNodes(); + writer.skipEdges(); + + writer.run(); + + lemon::GraphWriter writer2(graph, std::cout); +} + +void checkBpGraphReaderCompile() { + typedef lemon::concepts::ExtendableBpGraphComponent< + lemon::concepts::BpGraph> BpGraph; + BpGraph graph; + BpGraph::NodeMap node_map(graph); + BpGraph::RedNodeMap red_node_map(graph); + BpGraph::BlueNodeMap blue_node_map(graph); + BpGraph::ArcMap arc_map(graph); + BpGraph::EdgeMap edge_map(graph); + BpGraph::Node node; + BpGraph::RedNode red_node; + BpGraph::BlueNode blue_node; + BpGraph::Arc arc; + BpGraph::Edge edge; + int attr; + + lemon::BpGraphReader reader(graph, "filename"); + reader.nodeMap("node_map", node_map); + reader.nodeMap("node_map", node_map, ReaderConverter()); + reader.redNodeMap("red_node_map", red_node_map); + reader.redNodeMap("red_node_map", red_node_map, ReaderConverter()); + reader.blueNodeMap("blue_node_map", blue_node_map); + reader.blueNodeMap("blue_node_map", blue_node_map, ReaderConverter()); + reader.arcMap("arc_map", arc_map); + reader.arcMap("arc_map", arc_map, ReaderConverter()); + reader.edgeMap("edge_map", edge_map); + reader.edgeMap("edge_map", edge_map, ReaderConverter()); + reader.attribute("attr", attr); + reader.attribute("attr", attr, ReaderConverter()); + reader.node("node", node); + reader.redNode("red_node", red_node); + reader.blueNode("blue_node", blue_node); + reader.arc("arc", arc); + + reader.nodes("alt_nodes_caption"); + reader.edges("alt_edges_caption"); + reader.attributes("alt_attrs_caption"); + + reader.useNodes(node_map); + reader.useNodes(node_map, WriterConverter()); + reader.useEdges(edge_map); + reader.useEdges(edge_map, WriterConverter()); + + reader.skipNodes(); + reader.skipEdges(); + + reader.run(); + + lemon::BpGraphReader reader2(graph, std::cin); +} + +void checkBpGraphWriterCompile() { + typedef lemon::concepts::BpGraph BpGraph; + BpGraph graph; + BpGraph::NodeMap node_map(graph); + BpGraph::RedNodeMap red_node_map(graph); + BpGraph::BlueNodeMap blue_node_map(graph); + BpGraph::ArcMap arc_map(graph); + BpGraph::EdgeMap edge_map(graph); + BpGraph::Node node; + BpGraph::RedNode red_node; + BpGraph::BlueNode blue_node; + BpGraph::Arc arc; + BpGraph::Edge edge; + int attr; + + lemon::BpGraphWriter writer(graph, "filename"); + writer.nodeMap("node_map", node_map); + writer.nodeMap("node_map", node_map, WriterConverter()); + writer.redNodeMap("red_node_map", red_node_map); + writer.redNodeMap("red_node_map", red_node_map, WriterConverter()); + writer.blueNodeMap("blue_node_map", blue_node_map); + writer.blueNodeMap("blue_node_map", blue_node_map, WriterConverter()); + writer.arcMap("arc_map", arc_map); + writer.arcMap("arc_map", arc_map, WriterConverter()); + writer.edgeMap("edge_map", edge_map); + writer.edgeMap("edge_map", edge_map, WriterConverter()); + writer.attribute("attr", attr); + writer.attribute("attr", attr, WriterConverter()); + writer.node("node", node); + writer.redNode("red_node", red_node); + writer.blueNode("blue_node", blue_node); + writer.arc("arc", arc); + + writer.nodes("alt_nodes_caption"); + writer.edges("alt_edges_caption"); + writer.attributes("alt_attrs_caption"); + + writer.skipNodes(); + writer.skipEdges(); + + writer.run(); + + lemon::BpGraphWriter writer2(graph, std::cout); +} + +void checkDigraphReaderWriter() { + typedef lemon::SmartDigraph Digraph; + Digraph digraph; + Digraph::Node n1 = digraph.addNode(); + Digraph::Node n2 = digraph.addNode(); + Digraph::Node n3 = digraph.addNode(); + + Digraph::Arc a1 = digraph.addArc(n1, n2); + Digraph::Arc a2 = digraph.addArc(n2, n3); + + Digraph::NodeMap node_map(digraph); + node_map[n1] = 11; + node_map[n2] = 12; + node_map[n3] = 13; + + Digraph::ArcMap arc_map(digraph); + arc_map[a1] = 21; + arc_map[a2] = 22; + + int attr = 100; + + std::ostringstream os; + lemon::DigraphWriter writer(digraph, os); + + writer.nodeMap("node_map1", node_map); + writer.nodeMap("node_map2", node_map, WriterConverter()); + writer.arcMap("arc_map1", arc_map); + writer.arcMap("arc_map2", arc_map, WriterConverter()); + writer.node("node", n2); + writer.arc("arc", a1); + writer.attribute("attr1", attr); + writer.attribute("attr2", attr, WriterConverter()); + + writer.run(); + + typedef lemon::ListDigraph ExpDigraph; + ExpDigraph exp_digraph; + ExpDigraph::NodeMap exp_node_map1(exp_digraph); + ExpDigraph::NodeMap exp_node_map2(exp_digraph); + ExpDigraph::ArcMap exp_arc_map1(exp_digraph); + ExpDigraph::ArcMap exp_arc_map2(exp_digraph); + ExpDigraph::Node exp_n2; + ExpDigraph::Arc exp_a1; + int exp_attr1; + int exp_attr2; + + std::istringstream is(os.str()); + lemon::DigraphReader reader(exp_digraph, is); + + reader.nodeMap("node_map1", exp_node_map1); + reader.nodeMap("node_map2", exp_node_map2, ReaderConverter()); + reader.arcMap("arc_map1", exp_arc_map1); + reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter()); + reader.node("node", exp_n2); + reader.arc("arc", exp_a1); + reader.attribute("attr1", exp_attr1); + reader.attribute("attr2", exp_attr2, ReaderConverter()); + + reader.run(); + + check(lemon::countNodes(exp_digraph) == 3, "Wrong number of nodes"); + check(lemon::countArcs(exp_digraph) == 2, "Wrong number of arcs"); + check(exp_node_map1[exp_n2] == 12, "Wrong map value"); + check(exp_node_map2[exp_n2] == 12, "Wrong map value"); + check(exp_arc_map1[exp_a1] == 21, "Wrong map value"); + check(exp_arc_map2[exp_a1] == 21, "Wrong map value"); + check(exp_attr1 == 100, "Wrong attr value"); + check(exp_attr2 == 100, "Wrong attr value"); +} + +void checkGraphReaderWriter() { + typedef lemon::SmartGraph Graph; + Graph graph; + Graph::Node n1 = graph.addNode(); + Graph::Node n2 = graph.addNode(); + Graph::Node n3 = graph.addNode(); + + Graph::Edge e1 = graph.addEdge(n1, n2); + Graph::Edge e2 = graph.addEdge(n2, n3); + + Graph::NodeMap node_map(graph); + node_map[n1] = 11; + node_map[n2] = 12; + node_map[n3] = 13; + + Graph::EdgeMap edge_map(graph); + edge_map[e1] = 21; + edge_map[e2] = 22; + + Graph::ArcMap arc_map(graph); + arc_map[graph.direct(e1, true)] = 211; + arc_map[graph.direct(e1, false)] = 212; + arc_map[graph.direct(e2, true)] = 221; + arc_map[graph.direct(e2, false)] = 222; + + int attr = 100; + + std::ostringstream os; + lemon::GraphWriter writer(graph, os); + + writer.nodeMap("node_map1", node_map); + writer.nodeMap("node_map2", node_map, WriterConverter()); + writer.edgeMap("edge_map1", edge_map); + writer.edgeMap("edge_map2", edge_map, WriterConverter()); + writer.arcMap("arc_map1", arc_map); + writer.arcMap("arc_map2", arc_map, WriterConverter()); + writer.node("node", n2); + writer.edge("edge", e1); + writer.arc("arc", graph.direct(e1, false)); + writer.attribute("attr1", attr); + writer.attribute("attr2", attr, WriterConverter()); + + writer.run(); + + typedef lemon::ListGraph ExpGraph; + ExpGraph exp_graph; + ExpGraph::NodeMap exp_node_map1(exp_graph); + ExpGraph::NodeMap exp_node_map2(exp_graph); + ExpGraph::EdgeMap exp_edge_map1(exp_graph); + ExpGraph::EdgeMap exp_edge_map2(exp_graph); + ExpGraph::ArcMap exp_arc_map1(exp_graph); + ExpGraph::ArcMap exp_arc_map2(exp_graph); + ExpGraph::Node exp_n2; + ExpGraph::Edge exp_e1; + ExpGraph::Arc exp_a1; + int exp_attr1; + int exp_attr2; + + std::istringstream is(os.str()); + lemon::GraphReader reader(exp_graph, is); + + reader.nodeMap("node_map1", exp_node_map1); + reader.nodeMap("node_map2", exp_node_map2, ReaderConverter()); + reader.edgeMap("edge_map1", exp_edge_map1); + reader.edgeMap("edge_map2", exp_edge_map2, ReaderConverter()); + reader.arcMap("arc_map1", exp_arc_map1); + reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter()); + reader.node("node", exp_n2); + reader.edge("edge", exp_e1); + reader.arc("arc", exp_a1); + reader.attribute("attr1", exp_attr1); + reader.attribute("attr2", exp_attr2, ReaderConverter()); + + reader.run(); + + check(lemon::countNodes(exp_graph) == 3, "Wrong number of nodes"); + check(lemon::countEdges(exp_graph) == 2, "Wrong number of edges"); + check(lemon::countArcs(exp_graph) == 4, "Wrong number of arcs"); + check(exp_node_map1[exp_n2] == 12, "Wrong map value"); + check(exp_node_map2[exp_n2] == 12, "Wrong map value"); + check(exp_edge_map1[exp_e1] == 21, "Wrong map value"); + check(exp_edge_map2[exp_e1] == 21, "Wrong map value"); + check(exp_arc_map1[exp_a1] == 212, "Wrong map value"); + check(exp_arc_map2[exp_a1] == 212, "Wrong map value"); + check(exp_attr1 == 100, "Wrong attr value"); + check(exp_attr2 == 100, "Wrong attr value"); +} + +void checkBpGraphReaderWriter() { + typedef lemon::SmartBpGraph Graph; + Graph graph; + Graph::RedNode rn1 = graph.addRedNode(); + Graph::RedNode rn2 = graph.addRedNode(); + Graph::RedNode rn3 = graph.addRedNode(); + Graph::BlueNode bn1 = graph.addBlueNode(); + Graph::BlueNode bn2 = graph.addBlueNode(); + Graph::Node n = bn1; + + Graph::Edge e1 = graph.addEdge(rn1, bn1); + Graph::Edge e2 = graph.addEdge(rn2, bn1); + + Graph::NodeMap node_map(graph); + node_map[rn1] = 11; + node_map[rn2] = 12; + node_map[rn3] = 13; + node_map[bn1] = 14; + node_map[bn2] = 15; + + Graph::NodeMap red_node_map(graph); + red_node_map[rn1] = 411; + red_node_map[rn2] = 412; + red_node_map[rn3] = 413; + + Graph::NodeMap blue_node_map(graph); + blue_node_map[bn1] = 414; + blue_node_map[bn2] = 415; + + Graph::EdgeMap edge_map(graph); + edge_map[e1] = 21; + edge_map[e2] = 22; + + Graph::ArcMap arc_map(graph); + arc_map[graph.direct(e1, true)] = 211; + arc_map[graph.direct(e1, false)] = 212; + arc_map[graph.direct(e2, true)] = 221; + arc_map[graph.direct(e2, false)] = 222; + + int attr = 100; + + std::ostringstream os; + lemon::BpGraphWriter writer(graph, os); + + writer.nodeMap("node_map1", node_map); + writer.nodeMap("node_map2", node_map, WriterConverter()); + writer.nodeMap("red_node_map1", red_node_map); + writer.nodeMap("red_node_map2", red_node_map, WriterConverter()); + writer.nodeMap("blue_node_map1", blue_node_map); + writer.nodeMap("blue_node_map2", blue_node_map, WriterConverter()); + writer.edgeMap("edge_map1", edge_map); + writer.edgeMap("edge_map2", edge_map, WriterConverter()); + writer.arcMap("arc_map1", arc_map); + writer.arcMap("arc_map2", arc_map, WriterConverter()); + writer.node("node", n); + writer.redNode("red_node", rn1); + writer.blueNode("blue_node", bn2); + writer.edge("edge", e1); + writer.arc("arc", graph.direct(e1, false)); + writer.attribute("attr1", attr); + writer.attribute("attr2", attr, WriterConverter()); + + writer.run(); + + typedef lemon::ListBpGraph ExpGraph; + ExpGraph exp_graph; + ExpGraph::NodeMap exp_node_map1(exp_graph); + ExpGraph::NodeMap exp_node_map2(exp_graph); + ExpGraph::RedNodeMap exp_red_node_map1(exp_graph); + ExpGraph::RedNodeMap exp_red_node_map2(exp_graph); + ExpGraph::BlueNodeMap exp_blue_node_map1(exp_graph); + ExpGraph::BlueNodeMap exp_blue_node_map2(exp_graph); + ExpGraph::EdgeMap exp_edge_map1(exp_graph); + ExpGraph::EdgeMap exp_edge_map2(exp_graph); + ExpGraph::ArcMap exp_arc_map1(exp_graph); + ExpGraph::ArcMap exp_arc_map2(exp_graph); + ExpGraph::Node exp_n; + ExpGraph::RedNode exp_rn1; + ExpGraph::BlueNode exp_bn2; + ExpGraph::Edge exp_e1; + ExpGraph::Arc exp_a1; + int exp_attr1; + int exp_attr2; + + std::istringstream is(os.str()); + lemon::BpGraphReader reader(exp_graph, is); + + reader.nodeMap("node_map1", exp_node_map1); + reader.nodeMap("node_map2", exp_node_map2, ReaderConverter()); + reader.redNodeMap("red_node_map1", exp_red_node_map1); + reader.redNodeMap("red_node_map2", exp_red_node_map2, ReaderConverter()); + reader.blueNodeMap("blue_node_map1", exp_blue_node_map1); + reader.blueNodeMap("blue_node_map2", exp_blue_node_map2, ReaderConverter()); + reader.edgeMap("edge_map1", exp_edge_map1); + reader.edgeMap("edge_map2", exp_edge_map2, ReaderConverter()); + reader.arcMap("arc_map1", exp_arc_map1); + reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter()); + reader.node("node", exp_n); + reader.redNode("red_node", exp_rn1); + reader.blueNode("blue_node", exp_bn2); + reader.edge("edge", exp_e1); + reader.arc("arc", exp_a1); + reader.attribute("attr1", exp_attr1); + reader.attribute("attr2", exp_attr2, ReaderConverter()); + + reader.run(); + + check(lemon::countNodes(exp_graph) == 5, "Wrong number of nodes"); + check(lemon::countRedNodes(exp_graph) == 3, "Wrong number of red nodes"); + check(lemon::countBlueNodes(exp_graph) == 2, "Wrong number of blue nodes"); + check(lemon::countEdges(exp_graph) == 2, "Wrong number of edges"); + check(lemon::countArcs(exp_graph) == 4, "Wrong number of arcs"); + check(exp_node_map1[exp_n] == 14, "Wrong map value"); + check(exp_node_map2[exp_n] == 14, "Wrong map value"); + check(exp_red_node_map1[exp_rn1] == 411, "Wrong map value"); + check(exp_red_node_map2[exp_rn1] == 411, "Wrong map value"); + check(exp_blue_node_map1[exp_bn2] == 415, "Wrong map value"); + check(exp_blue_node_map2[exp_bn2] == 415, "Wrong map value"); + check(exp_edge_map1[exp_e1] == 21, "Wrong map value"); + check(exp_edge_map2[exp_e1] == 21, "Wrong map value"); + check(exp_arc_map1[exp_a1] == 212, "Wrong map value"); + check(exp_arc_map2[exp_a1] == 212, "Wrong map value"); + check(exp_attr1 == 100, "Wrong attr value"); + check(exp_attr2 == 100, "Wrong attr value"); +} + + +int main() { + { // Check digrpah + checkDigraphReaderWriter(); + } + { // Check graph + checkGraphReaderWriter(); + } + { // Check bipartite graph + checkBpGraphReaderWriter(); + } + return 0; +}