1.1 --- a/lemon/lgf_reader.h Tue Nov 16 08:19:11 2010 +0100
1.2 +++ b/lemon/lgf_reader.h Thu Nov 25 22:45:29 2010 +0100
1.3 @@ -2128,6 +2128,1046 @@
1.4 return tmp;
1.5 }
1.6
1.7 + template <typename BGR>
1.8 + class BpGraphReader;
1.9 +
1.10 + template <typename TBGR>
1.11 + BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is = std::cin);
1.12 + template <typename TBGR>
1.13 + BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn);
1.14 + template <typename TBGR>
1.15 + BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn);
1.16 +
1.17 + /// \ingroup lemon_io
1.18 + ///
1.19 + /// \brief \ref lgf-format "LGF" reader for bipartite graphs
1.20 + ///
1.21 + /// This utility reads an \ref lgf-format "LGF" file.
1.22 + ///
1.23 + /// It can be used almost the same way as \c GraphReader, but it
1.24 + /// reads the red and blue nodes from separate sections, and these
1.25 + /// sections can contain different set of maps.
1.26 + ///
1.27 + /// The red and blue maps are read from the corresponding
1.28 + /// sections. If a map is defined with the same name in both of
1.29 + /// these sections, then it can be read as a node map.
1.30 + template <typename BGR>
1.31 + class BpGraphReader {
1.32 + public:
1.33 +
1.34 + typedef BGR Graph;
1.35 +
1.36 + private:
1.37 +
1.38 + TEMPLATE_BPGRAPH_TYPEDEFS(BGR);
1.39 +
1.40 + std::istream* _is;
1.41 + bool local_is;
1.42 + std::string _filename;
1.43 +
1.44 + BGR& _graph;
1.45 +
1.46 + std::string _nodes_caption;
1.47 + std::string _edges_caption;
1.48 + std::string _attributes_caption;
1.49 +
1.50 + typedef std::map<std::string, Node> NodeIndex;
1.51 + NodeIndex _node_index;
1.52 + typedef std::map<std::string, Edge> EdgeIndex;
1.53 + EdgeIndex _edge_index;
1.54 +
1.55 + typedef std::vector<std::pair<std::string,
1.56 + _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1.57 + NodeMaps _red_maps;
1.58 + NodeMaps _blue_maps;
1.59 +
1.60 + typedef std::vector<std::pair<std::string,
1.61 + _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1.62 + EdgeMaps _edge_maps;
1.63 +
1.64 + typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1.65 + Attributes;
1.66 + Attributes _attributes;
1.67 +
1.68 + bool _use_nodes;
1.69 + bool _use_edges;
1.70 +
1.71 + bool _skip_nodes;
1.72 + bool _skip_edges;
1.73 +
1.74 + int line_num;
1.75 + std::istringstream line;
1.76 +
1.77 + public:
1.78 +
1.79 + /// \brief Constructor
1.80 + ///
1.81 + /// Construct an undirected graph reader, which reads from the given
1.82 + /// input stream.
1.83 + BpGraphReader(BGR& graph, std::istream& is = std::cin)
1.84 + : _is(&is), local_is(false), _graph(graph),
1.85 + _use_nodes(false), _use_edges(false),
1.86 + _skip_nodes(false), _skip_edges(false) {}
1.87 +
1.88 + /// \brief Constructor
1.89 + ///
1.90 + /// Construct an undirected graph reader, which reads from the given
1.91 + /// file.
1.92 + BpGraphReader(BGR& graph, const std::string& fn)
1.93 + : _is(new std::ifstream(fn.c_str())), local_is(true),
1.94 + _filename(fn), _graph(graph),
1.95 + _use_nodes(false), _use_edges(false),
1.96 + _skip_nodes(false), _skip_edges(false) {
1.97 + if (!(*_is)) {
1.98 + delete _is;
1.99 + throw IoError("Cannot open file", fn);
1.100 + }
1.101 + }
1.102 +
1.103 + /// \brief Constructor
1.104 + ///
1.105 + /// Construct an undirected graph reader, which reads from the given
1.106 + /// file.
1.107 + BpGraphReader(BGR& graph, const char* fn)
1.108 + : _is(new std::ifstream(fn)), local_is(true),
1.109 + _filename(fn), _graph(graph),
1.110 + _use_nodes(false), _use_edges(false),
1.111 + _skip_nodes(false), _skip_edges(false) {
1.112 + if (!(*_is)) {
1.113 + delete _is;
1.114 + throw IoError("Cannot open file", fn);
1.115 + }
1.116 + }
1.117 +
1.118 + /// \brief Destructor
1.119 + ~BpGraphReader() {
1.120 + for (typename NodeMaps::iterator it = _red_maps.begin();
1.121 + it != _red_maps.end(); ++it) {
1.122 + delete it->second;
1.123 + }
1.124 +
1.125 + for (typename NodeMaps::iterator it = _blue_maps.begin();
1.126 + it != _blue_maps.end(); ++it) {
1.127 + delete it->second;
1.128 + }
1.129 +
1.130 + for (typename EdgeMaps::iterator it = _edge_maps.begin();
1.131 + it != _edge_maps.end(); ++it) {
1.132 + delete it->second;
1.133 + }
1.134 +
1.135 + for (typename Attributes::iterator it = _attributes.begin();
1.136 + it != _attributes.end(); ++it) {
1.137 + delete it->second;
1.138 + }
1.139 +
1.140 + if (local_is) {
1.141 + delete _is;
1.142 + }
1.143 +
1.144 + }
1.145 +
1.146 + private:
1.147 + template <typename TBGR>
1.148 + friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is);
1.149 + template <typename TBGR>
1.150 + friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph,
1.151 + const std::string& fn);
1.152 + template <typename TBGR>
1.153 + friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn);
1.154 +
1.155 + BpGraphReader(BpGraphReader& other)
1.156 + : _is(other._is), local_is(other.local_is), _graph(other._graph),
1.157 + _use_nodes(other._use_nodes), _use_edges(other._use_edges),
1.158 + _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1.159 +
1.160 + other._is = 0;
1.161 + other.local_is = false;
1.162 +
1.163 + _node_index.swap(other._node_index);
1.164 + _edge_index.swap(other._edge_index);
1.165 +
1.166 + _red_maps.swap(other._red_maps);
1.167 + _blue_maps.swap(other._blue_maps);
1.168 + _edge_maps.swap(other._edge_maps);
1.169 + _attributes.swap(other._attributes);
1.170 +
1.171 + _nodes_caption = other._nodes_caption;
1.172 + _edges_caption = other._edges_caption;
1.173 + _attributes_caption = other._attributes_caption;
1.174 +
1.175 + }
1.176 +
1.177 + BpGraphReader& operator=(const BpGraphReader&);
1.178 +
1.179 + public:
1.180 +
1.181 + /// \name Reading Rules
1.182 + /// @{
1.183 +
1.184 + /// \brief Node map reading rule
1.185 + ///
1.186 + /// Add a node map reading rule to the reader.
1.187 + template <typename Map>
1.188 + BpGraphReader& nodeMap(const std::string& caption, Map& map) {
1.189 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1.190 + _reader_bits::MapStorageBase<Node>* red_storage =
1.191 + new _reader_bits::MapStorage<Node, Map>(map);
1.192 + _red_maps.push_back(std::make_pair(caption, red_storage));
1.193 + _reader_bits::MapStorageBase<Node>* blue_storage =
1.194 + new _reader_bits::MapStorage<Node, Map>(map);
1.195 + _blue_maps.push_back(std::make_pair(caption, blue_storage));
1.196 + return *this;
1.197 + }
1.198 +
1.199 + /// \brief Node map reading rule
1.200 + ///
1.201 + /// Add a node map reading rule with specialized converter to the
1.202 + /// reader.
1.203 + template <typename Map, typename Converter>
1.204 + BpGraphReader& nodeMap(const std::string& caption, Map& map,
1.205 + const Converter& converter = Converter()) {
1.206 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1.207 + _reader_bits::MapStorageBase<Node>* red_storage =
1.208 + new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1.209 + _red_maps.push_back(std::make_pair(caption, red_storage));
1.210 + _reader_bits::MapStorageBase<Node>* blue_storage =
1.211 + new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1.212 + _blue_maps.push_back(std::make_pair(caption, blue_storage));
1.213 + return *this;
1.214 + }
1.215 +
1.216 + /// Add a red map reading rule to the reader.
1.217 + template <typename Map>
1.218 + BpGraphReader& redMap(const std::string& caption, Map& map) {
1.219 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1.220 + _reader_bits::MapStorageBase<Node>* storage =
1.221 + new _reader_bits::MapStorage<Node, Map>(map);
1.222 + _red_maps.push_back(std::make_pair(caption, storage));
1.223 + return *this;
1.224 + }
1.225 +
1.226 + /// \brief Red map reading rule
1.227 + ///
1.228 + /// Add a red map reading rule with specialized converter to the
1.229 + /// reader.
1.230 + template <typename Map, typename Converter>
1.231 + BpGraphReader& redMap(const std::string& caption, Map& map,
1.232 + const Converter& converter = Converter()) {
1.233 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1.234 + _reader_bits::MapStorageBase<Node>* storage =
1.235 + new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1.236 + _red_maps.push_back(std::make_pair(caption, storage));
1.237 + return *this;
1.238 + }
1.239 +
1.240 + /// Add a blue map reading rule to the reader.
1.241 + template <typename Map>
1.242 + BpGraphReader& blueMap(const std::string& caption, Map& map) {
1.243 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1.244 + _reader_bits::MapStorageBase<Node>* storage =
1.245 + new _reader_bits::MapStorage<Node, Map>(map);
1.246 + _blue_maps.push_back(std::make_pair(caption, storage));
1.247 + return *this;
1.248 + }
1.249 +
1.250 + /// \brief Blue map reading rule
1.251 + ///
1.252 + /// Add a blue map reading rule with specialized converter to the
1.253 + /// reader.
1.254 + template <typename Map, typename Converter>
1.255 + BpGraphReader& blueMap(const std::string& caption, Map& map,
1.256 + const Converter& converter = Converter()) {
1.257 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1.258 + _reader_bits::MapStorageBase<Node>* storage =
1.259 + new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1.260 + _blue_maps.push_back(std::make_pair(caption, storage));
1.261 + return *this;
1.262 + }
1.263 +
1.264 + /// \brief Edge map reading rule
1.265 + ///
1.266 + /// Add an edge map reading rule to the reader.
1.267 + template <typename Map>
1.268 + BpGraphReader& edgeMap(const std::string& caption, Map& map) {
1.269 + checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1.270 + _reader_bits::MapStorageBase<Edge>* storage =
1.271 + new _reader_bits::MapStorage<Edge, Map>(map);
1.272 + _edge_maps.push_back(std::make_pair(caption, storage));
1.273 + return *this;
1.274 + }
1.275 +
1.276 + /// \brief Edge map reading rule
1.277 + ///
1.278 + /// Add an edge map reading rule with specialized converter to the
1.279 + /// reader.
1.280 + template <typename Map, typename Converter>
1.281 + BpGraphReader& edgeMap(const std::string& caption, Map& map,
1.282 + const Converter& converter = Converter()) {
1.283 + checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1.284 + _reader_bits::MapStorageBase<Edge>* storage =
1.285 + new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1.286 + _edge_maps.push_back(std::make_pair(caption, storage));
1.287 + return *this;
1.288 + }
1.289 +
1.290 + /// \brief Arc map reading rule
1.291 + ///
1.292 + /// Add an arc map reading rule to the reader.
1.293 + template <typename Map>
1.294 + BpGraphReader& arcMap(const std::string& caption, Map& map) {
1.295 + checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1.296 + _reader_bits::MapStorageBase<Edge>* forward_storage =
1.297 + new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1.298 + _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1.299 + _reader_bits::MapStorageBase<Edge>* backward_storage =
1.300 + new _reader_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map);
1.301 + _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1.302 + return *this;
1.303 + }
1.304 +
1.305 + /// \brief Arc map reading rule
1.306 + ///
1.307 + /// Add an arc map reading rule with specialized converter to the
1.308 + /// reader.
1.309 + template <typename Map, typename Converter>
1.310 + BpGraphReader& arcMap(const std::string& caption, Map& map,
1.311 + const Converter& converter = Converter()) {
1.312 + checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1.313 + _reader_bits::MapStorageBase<Edge>* forward_storage =
1.314 + new _reader_bits::GraphArcMapStorage<BGR, true, Map, Converter>
1.315 + (_graph, map, converter);
1.316 + _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1.317 + _reader_bits::MapStorageBase<Edge>* backward_storage =
1.318 + new _reader_bits::GraphArcMapStorage<BGR, false, Map, Converter>
1.319 + (_graph, map, converter);
1.320 + _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1.321 + return *this;
1.322 + }
1.323 +
1.324 + /// \brief Attribute reading rule
1.325 + ///
1.326 + /// Add an attribute reading rule to the reader.
1.327 + template <typename Value>
1.328 + BpGraphReader& attribute(const std::string& caption, Value& value) {
1.329 + _reader_bits::ValueStorageBase* storage =
1.330 + new _reader_bits::ValueStorage<Value>(value);
1.331 + _attributes.insert(std::make_pair(caption, storage));
1.332 + return *this;
1.333 + }
1.334 +
1.335 + /// \brief Attribute reading rule
1.336 + ///
1.337 + /// Add an attribute reading rule with specialized converter to the
1.338 + /// reader.
1.339 + template <typename Value, typename Converter>
1.340 + BpGraphReader& attribute(const std::string& caption, Value& value,
1.341 + const Converter& converter = Converter()) {
1.342 + _reader_bits::ValueStorageBase* storage =
1.343 + new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1.344 + _attributes.insert(std::make_pair(caption, storage));
1.345 + return *this;
1.346 + }
1.347 +
1.348 + /// \brief Node reading rule
1.349 + ///
1.350 + /// Add a node reading rule to reader.
1.351 + BpGraphReader& node(const std::string& caption, Node& node) {
1.352 + typedef _reader_bits::MapLookUpConverter<Node> Converter;
1.353 + Converter converter(_node_index);
1.354 + _reader_bits::ValueStorageBase* storage =
1.355 + new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1.356 + _attributes.insert(std::make_pair(caption, storage));
1.357 + return *this;
1.358 + }
1.359 +
1.360 + /// \brief Edge reading rule
1.361 + ///
1.362 + /// Add an edge reading rule to reader.
1.363 + BpGraphReader& edge(const std::string& caption, Edge& edge) {
1.364 + typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1.365 + Converter converter(_edge_index);
1.366 + _reader_bits::ValueStorageBase* storage =
1.367 + new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1.368 + _attributes.insert(std::make_pair(caption, storage));
1.369 + return *this;
1.370 + }
1.371 +
1.372 + /// \brief Arc reading rule
1.373 + ///
1.374 + /// Add an arc reading rule to reader.
1.375 + BpGraphReader& arc(const std::string& caption, Arc& arc) {
1.376 + typedef _reader_bits::GraphArcLookUpConverter<BGR> Converter;
1.377 + Converter converter(_graph, _edge_index);
1.378 + _reader_bits::ValueStorageBase* storage =
1.379 + new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1.380 + _attributes.insert(std::make_pair(caption, storage));
1.381 + return *this;
1.382 + }
1.383 +
1.384 + /// @}
1.385 +
1.386 + /// \name Select Section by Name
1.387 + /// @{
1.388 +
1.389 + /// \brief Set \c \@nodes section to be read
1.390 + ///
1.391 + /// Set \c \@nodes section to be read.
1.392 + BpGraphReader& nodes(const std::string& caption) {
1.393 + _nodes_caption = caption;
1.394 + return *this;
1.395 + }
1.396 +
1.397 + /// \brief Set \c \@edges section to be read
1.398 + ///
1.399 + /// Set \c \@edges section to be read.
1.400 + BpGraphReader& edges(const std::string& caption) {
1.401 + _edges_caption = caption;
1.402 + return *this;
1.403 + }
1.404 +
1.405 + /// \brief Set \c \@attributes section to be read
1.406 + ///
1.407 + /// Set \c \@attributes section to be read.
1.408 + BpGraphReader& attributes(const std::string& caption) {
1.409 + _attributes_caption = caption;
1.410 + return *this;
1.411 + }
1.412 +
1.413 + /// @}
1.414 +
1.415 + /// \name Using Previously Constructed Node or Edge Set
1.416 + /// @{
1.417 +
1.418 + /// \brief Use previously constructed node set
1.419 + ///
1.420 + /// Use previously constructed node set, and specify the node
1.421 + /// label map.
1.422 + template <typename Map>
1.423 + BpGraphReader& useNodes(const Map& map) {
1.424 + checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1.425 + LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1.426 + _use_nodes = true;
1.427 + _writer_bits::DefaultConverter<typename Map::Value> converter;
1.428 + for (NodeIt n(_graph); n != INVALID; ++n) {
1.429 + _node_index.insert(std::make_pair(converter(map[n]), n));
1.430 + }
1.431 + return *this;
1.432 + }
1.433 +
1.434 + /// \brief Use previously constructed node set
1.435 + ///
1.436 + /// Use previously constructed node set, and specify the node
1.437 + /// label map and a functor which converts the label map values to
1.438 + /// \c std::string.
1.439 + template <typename Map, typename Converter>
1.440 + BpGraphReader& useNodes(const Map& map,
1.441 + const Converter& converter = Converter()) {
1.442 + checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1.443 + LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1.444 + _use_nodes = true;
1.445 + for (NodeIt n(_graph); n != INVALID; ++n) {
1.446 + _node_index.insert(std::make_pair(converter(map[n]), n));
1.447 + }
1.448 + return *this;
1.449 + }
1.450 +
1.451 + /// \brief Use previously constructed edge set
1.452 + ///
1.453 + /// Use previously constructed edge set, and specify the edge
1.454 + /// label map.
1.455 + template <typename Map>
1.456 + BpGraphReader& useEdges(const Map& map) {
1.457 + checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1.458 + LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1.459 + _use_edges = true;
1.460 + _writer_bits::DefaultConverter<typename Map::Value> converter;
1.461 + for (EdgeIt a(_graph); a != INVALID; ++a) {
1.462 + _edge_index.insert(std::make_pair(converter(map[a]), a));
1.463 + }
1.464 + return *this;
1.465 + }
1.466 +
1.467 + /// \brief Use previously constructed edge set
1.468 + ///
1.469 + /// Use previously constructed edge set, and specify the edge
1.470 + /// label map and a functor which converts the label map values to
1.471 + /// \c std::string.
1.472 + template <typename Map, typename Converter>
1.473 + BpGraphReader& useEdges(const Map& map,
1.474 + const Converter& converter = Converter()) {
1.475 + checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1.476 + LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1.477 + _use_edges = true;
1.478 + for (EdgeIt a(_graph); a != INVALID; ++a) {
1.479 + _edge_index.insert(std::make_pair(converter(map[a]), a));
1.480 + }
1.481 + return *this;
1.482 + }
1.483 +
1.484 + /// \brief Skip the reading of node section
1.485 + ///
1.486 + /// Omit the reading of the node section. This implies that each node
1.487 + /// map reading rule will be abandoned, and the nodes of the graph
1.488 + /// will not be constructed, which usually cause that the edge set
1.489 + /// could not be read due to lack of node name
1.490 + /// could not be read due to lack of node name resolving.
1.491 + /// Therefore \c skipEdges() function should also be used, or
1.492 + /// \c useNodes() should be used to specify the label of the nodes.
1.493 + BpGraphReader& skipNodes() {
1.494 + LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
1.495 + _skip_nodes = true;
1.496 + return *this;
1.497 + }
1.498 +
1.499 + /// \brief Skip the reading of edge section
1.500 + ///
1.501 + /// Omit the reading of the edge section. This implies that each edge
1.502 + /// map reading rule will be abandoned, and the edges of the graph
1.503 + /// will not be constructed.
1.504 + BpGraphReader& skipEdges() {
1.505 + LEMON_ASSERT(!_skip_edges, "Skip edges already set");
1.506 + _skip_edges = true;
1.507 + return *this;
1.508 + }
1.509 +
1.510 + /// @}
1.511 +
1.512 + private:
1.513 +
1.514 + bool readLine() {
1.515 + std::string str;
1.516 + while(++line_num, std::getline(*_is, str)) {
1.517 + line.clear(); line.str(str);
1.518 + char c;
1.519 + if (line >> std::ws >> c && c != '#') {
1.520 + line.putback(c);
1.521 + return true;
1.522 + }
1.523 + }
1.524 + return false;
1.525 + }
1.526 +
1.527 + bool readSuccess() {
1.528 + return static_cast<bool>(*_is);
1.529 + }
1.530 +
1.531 + void skipSection() {
1.532 + char c;
1.533 + while (readSuccess() && line >> c && c != '@') {
1.534 + readLine();
1.535 + }
1.536 + if (readSuccess()) {
1.537 + line.putback(c);
1.538 + }
1.539 + }
1.540 +
1.541 + void readRedNodes() {
1.542 +
1.543 + std::vector<int> map_index(_red_maps.size());
1.544 + int map_num, label_index;
1.545 +
1.546 + char c;
1.547 + if (!readLine() || !(line >> c) || c == '@') {
1.548 + if (readSuccess() && line) line.putback(c);
1.549 + if (!_red_maps.empty())
1.550 + throw FormatError("Cannot find map names");
1.551 + return;
1.552 + }
1.553 + line.putback(c);
1.554 +
1.555 + {
1.556 + std::map<std::string, int> maps;
1.557 +
1.558 + std::string map;
1.559 + int index = 0;
1.560 + while (_reader_bits::readToken(line, map)) {
1.561 + if (maps.find(map) != maps.end()) {
1.562 + std::ostringstream msg;
1.563 + msg << "Multiple occurence of red map: " << map;
1.564 + throw FormatError(msg.str());
1.565 + }
1.566 + maps.insert(std::make_pair(map, index));
1.567 + ++index;
1.568 + }
1.569 +
1.570 + for (int i = 0; i < static_cast<int>(_red_maps.size()); ++i) {
1.571 + std::map<std::string, int>::iterator jt =
1.572 + maps.find(_red_maps[i].first);
1.573 + if (jt == maps.end()) {
1.574 + std::ostringstream msg;
1.575 + msg << "Map not found: " << _red_maps[i].first;
1.576 + throw FormatError(msg.str());
1.577 + }
1.578 + map_index[i] = jt->second;
1.579 + }
1.580 +
1.581 + {
1.582 + std::map<std::string, int>::iterator jt = maps.find("label");
1.583 + if (jt != maps.end()) {
1.584 + label_index = jt->second;
1.585 + } else {
1.586 + label_index = -1;
1.587 + }
1.588 + }
1.589 + map_num = maps.size();
1.590 + }
1.591 +
1.592 + while (readLine() && line >> c && c != '@') {
1.593 + line.putback(c);
1.594 +
1.595 + std::vector<std::string> tokens(map_num);
1.596 + for (int i = 0; i < map_num; ++i) {
1.597 + if (!_reader_bits::readToken(line, tokens[i])) {
1.598 + std::ostringstream msg;
1.599 + msg << "Column not found (" << i + 1 << ")";
1.600 + throw FormatError(msg.str());
1.601 + }
1.602 + }
1.603 + if (line >> std::ws >> c)
1.604 + throw FormatError("Extra character at the end of line");
1.605 +
1.606 + Node n;
1.607 + if (!_use_nodes) {
1.608 + n = _graph.addRedNode();
1.609 + if (label_index != -1)
1.610 + _node_index.insert(std::make_pair(tokens[label_index], n));
1.611 + } else {
1.612 + if (label_index == -1)
1.613 + throw FormatError("Label map not found");
1.614 + typename std::map<std::string, Node>::iterator it =
1.615 + _node_index.find(tokens[label_index]);
1.616 + if (it == _node_index.end()) {
1.617 + std::ostringstream msg;
1.618 + msg << "Node with label not found: " << tokens[label_index];
1.619 + throw FormatError(msg.str());
1.620 + }
1.621 + n = it->second;
1.622 + }
1.623 +
1.624 + for (int i = 0; i < static_cast<int>(_red_maps.size()); ++i) {
1.625 + _red_maps[i].second->set(n, tokens[map_index[i]]);
1.626 + }
1.627 +
1.628 + }
1.629 + if (readSuccess()) {
1.630 + line.putback(c);
1.631 + }
1.632 + }
1.633 +
1.634 + void readBlueNodes() {
1.635 +
1.636 + std::vector<int> map_index(_blue_maps.size());
1.637 + int map_num, label_index;
1.638 +
1.639 + char c;
1.640 + if (!readLine() || !(line >> c) || c == '@') {
1.641 + if (readSuccess() && line) line.putback(c);
1.642 + if (!_blue_maps.empty())
1.643 + throw FormatError("Cannot find map names");
1.644 + return;
1.645 + }
1.646 + line.putback(c);
1.647 +
1.648 + {
1.649 + std::map<std::string, int> maps;
1.650 +
1.651 + std::string map;
1.652 + int index = 0;
1.653 + while (_reader_bits::readToken(line, map)) {
1.654 + if (maps.find(map) != maps.end()) {
1.655 + std::ostringstream msg;
1.656 + msg << "Multiple occurence of blue map: " << map;
1.657 + throw FormatError(msg.str());
1.658 + }
1.659 + maps.insert(std::make_pair(map, index));
1.660 + ++index;
1.661 + }
1.662 +
1.663 + for (int i = 0; i < static_cast<int>(_blue_maps.size()); ++i) {
1.664 + std::map<std::string, int>::iterator jt =
1.665 + maps.find(_blue_maps[i].first);
1.666 + if (jt == maps.end()) {
1.667 + std::ostringstream msg;
1.668 + msg << "Map not found: " << _blue_maps[i].first;
1.669 + throw FormatError(msg.str());
1.670 + }
1.671 + map_index[i] = jt->second;
1.672 + }
1.673 +
1.674 + {
1.675 + std::map<std::string, int>::iterator jt = maps.find("label");
1.676 + if (jt != maps.end()) {
1.677 + label_index = jt->second;
1.678 + } else {
1.679 + label_index = -1;
1.680 + }
1.681 + }
1.682 + map_num = maps.size();
1.683 + }
1.684 +
1.685 + while (readLine() && line >> c && c != '@') {
1.686 + line.putback(c);
1.687 +
1.688 + std::vector<std::string> tokens(map_num);
1.689 + for (int i = 0; i < map_num; ++i) {
1.690 + if (!_reader_bits::readToken(line, tokens[i])) {
1.691 + std::ostringstream msg;
1.692 + msg << "Column not found (" << i + 1 << ")";
1.693 + throw FormatError(msg.str());
1.694 + }
1.695 + }
1.696 + if (line >> std::ws >> c)
1.697 + throw FormatError("Extra character at the end of line");
1.698 +
1.699 + Node n;
1.700 + if (!_use_nodes) {
1.701 + n = _graph.addBlueNode();
1.702 + if (label_index != -1)
1.703 + _node_index.insert(std::make_pair(tokens[label_index], n));
1.704 + } else {
1.705 + if (label_index == -1)
1.706 + throw FormatError("Label map not found");
1.707 + typename std::map<std::string, Node>::iterator it =
1.708 + _node_index.find(tokens[label_index]);
1.709 + if (it == _node_index.end()) {
1.710 + std::ostringstream msg;
1.711 + msg << "Node with label not found: " << tokens[label_index];
1.712 + throw FormatError(msg.str());
1.713 + }
1.714 + n = it->second;
1.715 + }
1.716 +
1.717 + for (int i = 0; i < static_cast<int>(_blue_maps.size()); ++i) {
1.718 + _blue_maps[i].second->set(n, tokens[map_index[i]]);
1.719 + }
1.720 +
1.721 + }
1.722 + if (readSuccess()) {
1.723 + line.putback(c);
1.724 + }
1.725 + }
1.726 +
1.727 + void readEdges() {
1.728 +
1.729 + std::vector<int> map_index(_edge_maps.size());
1.730 + int map_num, label_index;
1.731 +
1.732 + char c;
1.733 + if (!readLine() || !(line >> c) || c == '@') {
1.734 + if (readSuccess() && line) line.putback(c);
1.735 + if (!_edge_maps.empty())
1.736 + throw FormatError("Cannot find map names");
1.737 + return;
1.738 + }
1.739 + line.putback(c);
1.740 +
1.741 + {
1.742 + std::map<std::string, int> maps;
1.743 +
1.744 + std::string map;
1.745 + int index = 0;
1.746 + while (_reader_bits::readToken(line, map)) {
1.747 + if (maps.find(map) != maps.end()) {
1.748 + std::ostringstream msg;
1.749 + msg << "Multiple occurence of edge map: " << map;
1.750 + throw FormatError(msg.str());
1.751 + }
1.752 + maps.insert(std::make_pair(map, index));
1.753 + ++index;
1.754 + }
1.755 +
1.756 + for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1.757 + std::map<std::string, int>::iterator jt =
1.758 + maps.find(_edge_maps[i].first);
1.759 + if (jt == maps.end()) {
1.760 + std::ostringstream msg;
1.761 + msg << "Map not found: " << _edge_maps[i].first;
1.762 + throw FormatError(msg.str());
1.763 + }
1.764 + map_index[i] = jt->second;
1.765 + }
1.766 +
1.767 + {
1.768 + std::map<std::string, int>::iterator jt = maps.find("label");
1.769 + if (jt != maps.end()) {
1.770 + label_index = jt->second;
1.771 + } else {
1.772 + label_index = -1;
1.773 + }
1.774 + }
1.775 + map_num = maps.size();
1.776 + }
1.777 +
1.778 + while (readLine() && line >> c && c != '@') {
1.779 + line.putback(c);
1.780 +
1.781 + std::string source_token;
1.782 + std::string target_token;
1.783 +
1.784 + if (!_reader_bits::readToken(line, source_token))
1.785 + throw FormatError("Red node not found");
1.786 +
1.787 + if (!_reader_bits::readToken(line, target_token))
1.788 + throw FormatError("Blue node not found");
1.789 +
1.790 + std::vector<std::string> tokens(map_num);
1.791 + for (int i = 0; i < map_num; ++i) {
1.792 + if (!_reader_bits::readToken(line, tokens[i])) {
1.793 + std::ostringstream msg;
1.794 + msg << "Column not found (" << i + 1 << ")";
1.795 + throw FormatError(msg.str());
1.796 + }
1.797 + }
1.798 + if (line >> std::ws >> c)
1.799 + throw FormatError("Extra character at the end of line");
1.800 +
1.801 + Edge e;
1.802 + if (!_use_edges) {
1.803 +
1.804 + typename NodeIndex::iterator it;
1.805 +
1.806 + it = _node_index.find(source_token);
1.807 + if (it == _node_index.end()) {
1.808 + std::ostringstream msg;
1.809 + msg << "Item not found: " << source_token;
1.810 + throw FormatError(msg.str());
1.811 + }
1.812 + Node source = it->second;
1.813 + if (!_graph.red(source)) {
1.814 + std::ostringstream msg;
1.815 + msg << "Item is not red node: " << source_token;
1.816 + throw FormatError(msg.str());
1.817 + }
1.818 +
1.819 + it = _node_index.find(target_token);
1.820 + if (it == _node_index.end()) {
1.821 + std::ostringstream msg;
1.822 + msg << "Item not found: " << target_token;
1.823 + throw FormatError(msg.str());
1.824 + }
1.825 + Node target = it->second;
1.826 + if (!_graph.blue(target)) {
1.827 + std::ostringstream msg;
1.828 + msg << "Item is not red node: " << source_token;
1.829 + throw FormatError(msg.str());
1.830 + }
1.831 +
1.832 + e = _graph.addEdge(source, target);
1.833 + if (label_index != -1)
1.834 + _edge_index.insert(std::make_pair(tokens[label_index], e));
1.835 + } else {
1.836 + if (label_index == -1)
1.837 + throw FormatError("Label map not found");
1.838 + typename std::map<std::string, Edge>::iterator it =
1.839 + _edge_index.find(tokens[label_index]);
1.840 + if (it == _edge_index.end()) {
1.841 + std::ostringstream msg;
1.842 + msg << "Edge with label not found: " << tokens[label_index];
1.843 + throw FormatError(msg.str());
1.844 + }
1.845 + e = it->second;
1.846 + }
1.847 +
1.848 + for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1.849 + _edge_maps[i].second->set(e, tokens[map_index[i]]);
1.850 + }
1.851 +
1.852 + }
1.853 + if (readSuccess()) {
1.854 + line.putback(c);
1.855 + }
1.856 + }
1.857 +
1.858 + void readAttributes() {
1.859 +
1.860 + std::set<std::string> read_attr;
1.861 +
1.862 + char c;
1.863 + while (readLine() && line >> c && c != '@') {
1.864 + line.putback(c);
1.865 +
1.866 + std::string attr, token;
1.867 + if (!_reader_bits::readToken(line, attr))
1.868 + throw FormatError("Attribute name not found");
1.869 + if (!_reader_bits::readToken(line, token))
1.870 + throw FormatError("Attribute value not found");
1.871 + if (line >> c)
1.872 + throw FormatError("Extra character at the end of line");
1.873 +
1.874 + {
1.875 + std::set<std::string>::iterator it = read_attr.find(attr);
1.876 + if (it != read_attr.end()) {
1.877 + std::ostringstream msg;
1.878 + msg << "Multiple occurence of attribute: " << attr;
1.879 + throw FormatError(msg.str());
1.880 + }
1.881 + read_attr.insert(attr);
1.882 + }
1.883 +
1.884 + {
1.885 + typename Attributes::iterator it = _attributes.lower_bound(attr);
1.886 + while (it != _attributes.end() && it->first == attr) {
1.887 + it->second->set(token);
1.888 + ++it;
1.889 + }
1.890 + }
1.891 +
1.892 + }
1.893 + if (readSuccess()) {
1.894 + line.putback(c);
1.895 + }
1.896 + for (typename Attributes::iterator it = _attributes.begin();
1.897 + it != _attributes.end(); ++it) {
1.898 + if (read_attr.find(it->first) == read_attr.end()) {
1.899 + std::ostringstream msg;
1.900 + msg << "Attribute not found: " << it->first;
1.901 + throw FormatError(msg.str());
1.902 + }
1.903 + }
1.904 + }
1.905 +
1.906 + public:
1.907 +
1.908 + /// \name Execution of the Reader
1.909 + /// @{
1.910 +
1.911 + /// \brief Start the batch processing
1.912 + ///
1.913 + /// This function starts the batch processing
1.914 + void run() {
1.915 +
1.916 + LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1.917 +
1.918 + bool red_nodes_done = _skip_nodes;
1.919 + bool blue_nodes_done = _skip_nodes;
1.920 + bool edges_done = _skip_edges;
1.921 + bool attributes_done = false;
1.922 +
1.923 + line_num = 0;
1.924 + readLine();
1.925 + skipSection();
1.926 +
1.927 + while (readSuccess()) {
1.928 + try {
1.929 + char c;
1.930 + std::string section, caption;
1.931 + line >> c;
1.932 + _reader_bits::readToken(line, section);
1.933 + _reader_bits::readToken(line, caption);
1.934 +
1.935 + if (line >> c)
1.936 + throw FormatError("Extra character at the end of line");
1.937 +
1.938 + if (section == "red_nodes" && !red_nodes_done) {
1.939 + if (_nodes_caption.empty() || _nodes_caption == caption) {
1.940 + readRedNodes();
1.941 + red_nodes_done = true;
1.942 + }
1.943 + } else if (section == "blue_nodes" && !blue_nodes_done) {
1.944 + if (_nodes_caption.empty() || _nodes_caption == caption) {
1.945 + readBlueNodes();
1.946 + blue_nodes_done = true;
1.947 + }
1.948 + } else if ((section == "edges" || section == "arcs") &&
1.949 + !edges_done) {
1.950 + if (_edges_caption.empty() || _edges_caption == caption) {
1.951 + readEdges();
1.952 + edges_done = true;
1.953 + }
1.954 + } else if (section == "attributes" && !attributes_done) {
1.955 + if (_attributes_caption.empty() || _attributes_caption == caption) {
1.956 + readAttributes();
1.957 + attributes_done = true;
1.958 + }
1.959 + } else {
1.960 + readLine();
1.961 + skipSection();
1.962 + }
1.963 + } catch (FormatError& error) {
1.964 + error.line(line_num);
1.965 + error.file(_filename);
1.966 + throw;
1.967 + }
1.968 + }
1.969 +
1.970 + if (!red_nodes_done) {
1.971 + throw FormatError("Section @red_nodes not found");
1.972 + }
1.973 +
1.974 + if (!blue_nodes_done) {
1.975 + throw FormatError("Section @blue_nodes not found");
1.976 + }
1.977 +
1.978 + if (!edges_done) {
1.979 + throw FormatError("Section @edges not found");
1.980 + }
1.981 +
1.982 + if (!attributes_done && !_attributes.empty()) {
1.983 + throw FormatError("Section @attributes not found");
1.984 + }
1.985 +
1.986 + }
1.987 +
1.988 + /// @}
1.989 +
1.990 + };
1.991 +
1.992 + /// \ingroup lemon_io
1.993 + ///
1.994 + /// \brief Return a \ref BpGraphReader class
1.995 + ///
1.996 + /// This function just returns a \ref BpGraphReader class.
1.997 + ///
1.998 + /// With this function a graph can be read from an
1.999 + /// \ref lgf-format "LGF" file or input stream with several maps and
1.1000 + /// attributes. For example, there is bipartite weighted matching problem
1.1001 + /// on a graph, i.e. a graph with a \e weight map on the edges. This
1.1002 + /// graph can be read with the following code:
1.1003 + ///
1.1004 + ///\code
1.1005 + ///ListBpGraph graph;
1.1006 + ///ListBpGraph::EdgeMap<int> weight(graph);
1.1007 + ///bpGraphReader(graph, std::cin).
1.1008 + /// edgeMap("weight", weight).
1.1009 + /// run();
1.1010 + ///\endcode
1.1011 + ///
1.1012 + /// For a complete documentation, please see the \ref BpGraphReader
1.1013 + /// class documentation.
1.1014 + /// \warning Don't forget to put the \ref BpGraphReader::run() "run()"
1.1015 + /// to the end of the parameter list.
1.1016 + /// \relates BpGraphReader
1.1017 + /// \sa bpGraphReader(TBGR& graph, const std::string& fn)
1.1018 + /// \sa bpGraphReader(TBGR& graph, const char* fn)
1.1019 + template <typename TBGR>
1.1020 + BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is) {
1.1021 + BpGraphReader<TBGR> tmp(graph, is);
1.1022 + return tmp;
1.1023 + }
1.1024 +
1.1025 + /// \brief Return a \ref BpGraphReader class
1.1026 + ///
1.1027 + /// This function just returns a \ref BpGraphReader class.
1.1028 + /// \relates BpGraphReader
1.1029 + /// \sa bpGraphReader(TBGR& graph, std::istream& is)
1.1030 + template <typename TBGR>
1.1031 + BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn) {
1.1032 + BpGraphReader<TBGR> tmp(graph, fn);
1.1033 + return tmp;
1.1034 + }
1.1035 +
1.1036 + /// \brief Return a \ref BpGraphReader class
1.1037 + ///
1.1038 + /// This function just returns a \ref BpGraphReader class.
1.1039 + /// \relates BpGraphReader
1.1040 + /// \sa bpGraphReader(TBGR& graph, std::istream& is)
1.1041 + template <typename TBGR>
1.1042 + BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char* fn) {
1.1043 + BpGraphReader<TBGR> tmp(graph, fn);
1.1044 + return tmp;
1.1045 + }
1.1046 +
1.1047 class SectionReader;
1.1048
1.1049 SectionReader sectionReader(std::istream& is);