Changes in lemon/lgf_reader.h [1110:02c93d1f00d7:1198:4936be66d2f5] in lemon
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/lgf_reader.h
r1110 r1198 155 155 }; 156 156 157 template <typename Value> 157 template <typename Value, 158 typename Map = std::map<std::string, Value> > 158 159 struct MapLookUpConverter { 159 const std::map<std::string, Value>& _map;160 161 MapLookUpConverter(const std::map<std::string, Value>& map)160 const Map& _map; 161 162 MapLookUpConverter(const Map& map) 162 163 : _map(map) {} 163 164 164 165 Value operator()(const std::string& str) { 165 typename std::map<std::string, Value>::const_iterator it = 166 _map.find(str); 166 typename Map::const_iterator it = _map.find(str); 167 167 if (it == _map.end()) { 168 168 std::ostringstream msg; … … 171 171 } 172 172 return it->second; 173 } 174 }; 175 176 template <typename Value, 177 typename Map1 = std::map<std::string, Value>, 178 typename Map2 = std::map<std::string, Value> > 179 struct DoubleMapLookUpConverter { 180 const Map1& _map1; 181 const Map2& _map2; 182 183 DoubleMapLookUpConverter(const Map1& map1, const Map2& map2) 184 : _map1(map1), _map2(map2) {} 185 186 Value operator()(const std::string& str) { 187 typename Map1::const_iterator it1 = _map1.find(str); 188 typename Map2::const_iterator it2 = _map2.find(str); 189 if (it1 == _map1.end()) { 190 if (it2 == _map2.end()) { 191 std::ostringstream msg; 192 msg << "Item not found: " << str; 193 throw FormatError(msg.str()); 194 } else { 195 return it2->second; 196 } 197 } else { 198 if (it2 == _map2.end()) { 199 return it1->second; 200 } else { 201 std::ostringstream msg; 202 msg << "Item is ambigous: " << str; 203 throw FormatError(msg.str()); 204 } 205 } 173 206 } 174 207 }; … … 2129 2162 } 2130 2163 2164 template <typename BGR> 2165 class BpGraphReader; 2166 2167 template <typename TBGR> 2168 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is = std::cin); 2169 template <typename TBGR> 2170 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn); 2171 template <typename TBGR> 2172 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn); 2173 2174 /// \ingroup lemon_io 2175 /// 2176 /// \brief \ref lgf-format "LGF" reader for bipartite graphs 2177 /// 2178 /// This utility reads an \ref lgf-format "LGF" file. 2179 /// 2180 /// It can be used almost the same way as \c GraphReader, but it 2181 /// reads the red and blue nodes from separate sections, and these 2182 /// sections can contain different set of maps. 2183 /// 2184 /// The red and blue node maps are read from the corresponding 2185 /// sections. If a map is defined with the same name in both of 2186 /// these sections, then it can be read as a node map. 2187 template <typename BGR> 2188 class BpGraphReader { 2189 public: 2190 2191 typedef BGR Graph; 2192 2193 private: 2194 2195 TEMPLATE_BPGRAPH_TYPEDEFS(BGR); 2196 2197 std::istream* _is; 2198 bool local_is; 2199 std::string _filename; 2200 2201 BGR& _graph; 2202 2203 std::string _nodes_caption; 2204 std::string _edges_caption; 2205 std::string _attributes_caption; 2206 2207 typedef std::map<std::string, RedNode> RedNodeIndex; 2208 RedNodeIndex _red_node_index; 2209 typedef std::map<std::string, BlueNode> BlueNodeIndex; 2210 BlueNodeIndex _blue_node_index; 2211 typedef std::map<std::string, Edge> EdgeIndex; 2212 EdgeIndex _edge_index; 2213 2214 typedef std::vector<std::pair<std::string, 2215 _reader_bits::MapStorageBase<RedNode>*> > RedNodeMaps; 2216 RedNodeMaps _red_node_maps; 2217 typedef std::vector<std::pair<std::string, 2218 _reader_bits::MapStorageBase<BlueNode>*> > BlueNodeMaps; 2219 BlueNodeMaps _blue_node_maps; 2220 2221 typedef std::vector<std::pair<std::string, 2222 _reader_bits::MapStorageBase<Edge>*> > EdgeMaps; 2223 EdgeMaps _edge_maps; 2224 2225 typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 2226 Attributes; 2227 Attributes _attributes; 2228 2229 bool _use_nodes; 2230 bool _use_edges; 2231 2232 bool _skip_nodes; 2233 bool _skip_edges; 2234 2235 int line_num; 2236 std::istringstream line; 2237 2238 public: 2239 2240 /// \brief Constructor 2241 /// 2242 /// Construct an undirected graph reader, which reads from the given 2243 /// input stream. 2244 BpGraphReader(BGR& graph, std::istream& is = std::cin) 2245 : _is(&is), local_is(false), _graph(graph), 2246 _use_nodes(false), _use_edges(false), 2247 _skip_nodes(false), _skip_edges(false) {} 2248 2249 /// \brief Constructor 2250 /// 2251 /// Construct an undirected graph reader, which reads from the given 2252 /// file. 2253 BpGraphReader(BGR& graph, const std::string& fn) 2254 : _is(new std::ifstream(fn.c_str())), local_is(true), 2255 _filename(fn), _graph(graph), 2256 _use_nodes(false), _use_edges(false), 2257 _skip_nodes(false), _skip_edges(false) { 2258 if (!(*_is)) { 2259 delete _is; 2260 throw IoError("Cannot open file", fn); 2261 } 2262 } 2263 2264 /// \brief Constructor 2265 /// 2266 /// Construct an undirected graph reader, which reads from the given 2267 /// file. 2268 BpGraphReader(BGR& graph, const char* fn) 2269 : _is(new std::ifstream(fn)), local_is(true), 2270 _filename(fn), _graph(graph), 2271 _use_nodes(false), _use_edges(false), 2272 _skip_nodes(false), _skip_edges(false) { 2273 if (!(*_is)) { 2274 delete _is; 2275 throw IoError("Cannot open file", fn); 2276 } 2277 } 2278 2279 /// \brief Destructor 2280 ~BpGraphReader() { 2281 for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); 2282 it != _red_node_maps.end(); ++it) { 2283 delete it->second; 2284 } 2285 2286 for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); 2287 it != _blue_node_maps.end(); ++it) { 2288 delete it->second; 2289 } 2290 2291 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 2292 it != _edge_maps.end(); ++it) { 2293 delete it->second; 2294 } 2295 2296 for (typename Attributes::iterator it = _attributes.begin(); 2297 it != _attributes.end(); ++it) { 2298 delete it->second; 2299 } 2300 2301 if (local_is) { 2302 delete _is; 2303 } 2304 2305 } 2306 2307 private: 2308 template <typename TBGR> 2309 friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is); 2310 template <typename TBGR> 2311 friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, 2312 const std::string& fn); 2313 template <typename TBGR> 2314 friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn); 2315 2316 BpGraphReader(BpGraphReader& other) 2317 : _is(other._is), local_is(other.local_is), _graph(other._graph), 2318 _use_nodes(other._use_nodes), _use_edges(other._use_edges), 2319 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) { 2320 2321 other._is = 0; 2322 other.local_is = false; 2323 2324 _red_node_index.swap(other._red_node_index); 2325 _blue_node_index.swap(other._blue_node_index); 2326 _edge_index.swap(other._edge_index); 2327 2328 _red_node_maps.swap(other._red_node_maps); 2329 _blue_node_maps.swap(other._blue_node_maps); 2330 _edge_maps.swap(other._edge_maps); 2331 _attributes.swap(other._attributes); 2332 2333 _nodes_caption = other._nodes_caption; 2334 _edges_caption = other._edges_caption; 2335 _attributes_caption = other._attributes_caption; 2336 2337 } 2338 2339 BpGraphReader& operator=(const BpGraphReader&); 2340 2341 public: 2342 2343 /// \name Reading Rules 2344 /// @{ 2345 2346 /// \brief Node map reading rule 2347 /// 2348 /// Add a node map reading rule to the reader. 2349 template <typename Map> 2350 BpGraphReader& nodeMap(const std::string& caption, Map& map) { 2351 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); 2352 _reader_bits::MapStorageBase<RedNode>* red_storage = 2353 new _reader_bits::MapStorage<RedNode, Map>(map); 2354 _red_node_maps.push_back(std::make_pair(caption, red_storage)); 2355 _reader_bits::MapStorageBase<BlueNode>* blue_storage = 2356 new _reader_bits::MapStorage<BlueNode, Map>(map); 2357 _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); 2358 return *this; 2359 } 2360 2361 /// \brief Node map reading rule 2362 /// 2363 /// Add a node map reading rule with specialized converter to the 2364 /// reader. 2365 template <typename Map, typename Converter> 2366 BpGraphReader& nodeMap(const std::string& caption, Map& map, 2367 const Converter& converter = Converter()) { 2368 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); 2369 _reader_bits::MapStorageBase<RedNode>* red_storage = 2370 new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter); 2371 _red_node_maps.push_back(std::make_pair(caption, red_storage)); 2372 _reader_bits::MapStorageBase<BlueNode>* blue_storage = 2373 new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter); 2374 _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); 2375 return *this; 2376 } 2377 2378 /// Add a red node map reading rule to the reader. 2379 template <typename Map> 2380 BpGraphReader& redNodeMap(const std::string& caption, Map& map) { 2381 checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>(); 2382 _reader_bits::MapStorageBase<RedNode>* storage = 2383 new _reader_bits::MapStorage<RedNode, Map>(map); 2384 _red_node_maps.push_back(std::make_pair(caption, storage)); 2385 return *this; 2386 } 2387 2388 /// \brief Red node map reading rule 2389 /// 2390 /// Add a red node map node reading rule with specialized converter to 2391 /// the reader. 2392 template <typename Map, typename Converter> 2393 BpGraphReader& redNodeMap(const std::string& caption, Map& map, 2394 const Converter& converter = Converter()) { 2395 checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>(); 2396 _reader_bits::MapStorageBase<RedNode>* storage = 2397 new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter); 2398 _red_node_maps.push_back(std::make_pair(caption, storage)); 2399 return *this; 2400 } 2401 2402 /// Add a blue node map reading rule to the reader. 2403 template <typename Map> 2404 BpGraphReader& blueNodeMap(const std::string& caption, Map& map) { 2405 checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>(); 2406 _reader_bits::MapStorageBase<BlueNode>* storage = 2407 new _reader_bits::MapStorage<BlueNode, Map>(map); 2408 _blue_node_maps.push_back(std::make_pair(caption, storage)); 2409 return *this; 2410 } 2411 2412 /// \brief Blue node map reading rule 2413 /// 2414 /// Add a blue node map reading rule with specialized converter to 2415 /// the reader. 2416 template <typename Map, typename Converter> 2417 BpGraphReader& blueNodeMap(const std::string& caption, Map& map, 2418 const Converter& converter = Converter()) { 2419 checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>(); 2420 _reader_bits::MapStorageBase<BlueNode>* storage = 2421 new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter); 2422 _blue_node_maps.push_back(std::make_pair(caption, storage)); 2423 return *this; 2424 } 2425 2426 /// \brief Edge map reading rule 2427 /// 2428 /// Add an edge map reading rule to the reader. 2429 template <typename Map> 2430 BpGraphReader& edgeMap(const std::string& caption, Map& map) { 2431 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); 2432 _reader_bits::MapStorageBase<Edge>* storage = 2433 new _reader_bits::MapStorage<Edge, Map>(map); 2434 _edge_maps.push_back(std::make_pair(caption, storage)); 2435 return *this; 2436 } 2437 2438 /// \brief Edge map reading rule 2439 /// 2440 /// Add an edge map reading rule with specialized converter to the 2441 /// reader. 2442 template <typename Map, typename Converter> 2443 BpGraphReader& edgeMap(const std::string& caption, Map& map, 2444 const Converter& converter = Converter()) { 2445 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); 2446 _reader_bits::MapStorageBase<Edge>* storage = 2447 new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter); 2448 _edge_maps.push_back(std::make_pair(caption, storage)); 2449 return *this; 2450 } 2451 2452 /// \brief Arc map reading rule 2453 /// 2454 /// Add an arc map reading rule to the reader. 2455 template <typename Map> 2456 BpGraphReader& arcMap(const std::string& caption, Map& map) { 2457 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); 2458 _reader_bits::MapStorageBase<Edge>* forward_storage = 2459 new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map); 2460 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 2461 _reader_bits::MapStorageBase<Edge>* backward_storage = 2462 new _reader_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map); 2463 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 2464 return *this; 2465 } 2466 2467 /// \brief Arc map reading rule 2468 /// 2469 /// Add an arc map reading rule with specialized converter to the 2470 /// reader. 2471 template <typename Map, typename Converter> 2472 BpGraphReader& arcMap(const std::string& caption, Map& map, 2473 const Converter& converter = Converter()) { 2474 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); 2475 _reader_bits::MapStorageBase<Edge>* forward_storage = 2476 new _reader_bits::GraphArcMapStorage<BGR, true, Map, Converter> 2477 (_graph, map, converter); 2478 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 2479 _reader_bits::MapStorageBase<Edge>* backward_storage = 2480 new _reader_bits::GraphArcMapStorage<BGR, false, Map, Converter> 2481 (_graph, map, converter); 2482 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 2483 return *this; 2484 } 2485 2486 /// \brief Attribute reading rule 2487 /// 2488 /// Add an attribute reading rule to the reader. 2489 template <typename Value> 2490 BpGraphReader& attribute(const std::string& caption, Value& value) { 2491 _reader_bits::ValueStorageBase* storage = 2492 new _reader_bits::ValueStorage<Value>(value); 2493 _attributes.insert(std::make_pair(caption, storage)); 2494 return *this; 2495 } 2496 2497 /// \brief Attribute reading rule 2498 /// 2499 /// Add an attribute reading rule with specialized converter to the 2500 /// reader. 2501 template <typename Value, typename Converter> 2502 BpGraphReader& attribute(const std::string& caption, Value& value, 2503 const Converter& converter = Converter()) { 2504 _reader_bits::ValueStorageBase* storage = 2505 new _reader_bits::ValueStorage<Value, Converter>(value, converter); 2506 _attributes.insert(std::make_pair(caption, storage)); 2507 return *this; 2508 } 2509 2510 /// \brief Node reading rule 2511 /// 2512 /// Add a node reading rule to reader. 2513 BpGraphReader& node(const std::string& caption, Node& node) { 2514 typedef _reader_bits::DoubleMapLookUpConverter< 2515 Node, RedNodeIndex, BlueNodeIndex> Converter; 2516 Converter converter(_red_node_index, _blue_node_index); 2517 _reader_bits::ValueStorageBase* storage = 2518 new _reader_bits::ValueStorage<Node, Converter>(node, converter); 2519 _attributes.insert(std::make_pair(caption, storage)); 2520 return *this; 2521 } 2522 2523 /// \brief Red node reading rule 2524 /// 2525 /// Add a red node reading rule to reader. 2526 BpGraphReader& redNode(const std::string& caption, RedNode& node) { 2527 typedef _reader_bits::MapLookUpConverter<RedNode> Converter; 2528 Converter converter(_red_node_index); 2529 _reader_bits::ValueStorageBase* storage = 2530 new _reader_bits::ValueStorage<RedNode, Converter>(node, converter); 2531 _attributes.insert(std::make_pair(caption, storage)); 2532 return *this; 2533 } 2534 2535 /// \brief Blue node reading rule 2536 /// 2537 /// Add a blue node reading rule to reader. 2538 BpGraphReader& blueNode(const std::string& caption, BlueNode& node) { 2539 typedef _reader_bits::MapLookUpConverter<BlueNode> Converter; 2540 Converter converter(_blue_node_index); 2541 _reader_bits::ValueStorageBase* storage = 2542 new _reader_bits::ValueStorage<BlueNode, Converter>(node, converter); 2543 _attributes.insert(std::make_pair(caption, storage)); 2544 return *this; 2545 } 2546 2547 /// \brief Edge reading rule 2548 /// 2549 /// Add an edge reading rule to reader. 2550 BpGraphReader& edge(const std::string& caption, Edge& edge) { 2551 typedef _reader_bits::MapLookUpConverter<Edge> Converter; 2552 Converter converter(_edge_index); 2553 _reader_bits::ValueStorageBase* storage = 2554 new _reader_bits::ValueStorage<Edge, Converter>(edge, converter); 2555 _attributes.insert(std::make_pair(caption, storage)); 2556 return *this; 2557 } 2558 2559 /// \brief Arc reading rule 2560 /// 2561 /// Add an arc reading rule to reader. 2562 BpGraphReader& arc(const std::string& caption, Arc& arc) { 2563 typedef _reader_bits::GraphArcLookUpConverter<BGR> Converter; 2564 Converter converter(_graph, _edge_index); 2565 _reader_bits::ValueStorageBase* storage = 2566 new _reader_bits::ValueStorage<Arc, Converter>(arc, converter); 2567 _attributes.insert(std::make_pair(caption, storage)); 2568 return *this; 2569 } 2570 2571 /// @} 2572 2573 /// \name Select Section by Name 2574 /// @{ 2575 2576 /// \brief Set \c \@nodes section to be read 2577 /// 2578 /// Set \c \@nodes section to be read. 2579 BpGraphReader& nodes(const std::string& caption) { 2580 _nodes_caption = caption; 2581 return *this; 2582 } 2583 2584 /// \brief Set \c \@edges section to be read 2585 /// 2586 /// Set \c \@edges section to be read. 2587 BpGraphReader& edges(const std::string& caption) { 2588 _edges_caption = caption; 2589 return *this; 2590 } 2591 2592 /// \brief Set \c \@attributes section to be read 2593 /// 2594 /// Set \c \@attributes section to be read. 2595 BpGraphReader& attributes(const std::string& caption) { 2596 _attributes_caption = caption; 2597 return *this; 2598 } 2599 2600 /// @} 2601 2602 /// \name Using Previously Constructed Node or Edge Set 2603 /// @{ 2604 2605 /// \brief Use previously constructed node set 2606 /// 2607 /// Use previously constructed node set, and specify the node 2608 /// label map. 2609 template <typename Map> 2610 BpGraphReader& useNodes(const Map& map) { 2611 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 2612 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 2613 _use_nodes = true; 2614 _writer_bits::DefaultConverter<typename Map::Value> converter; 2615 for (RedNodeIt n(_graph); n != INVALID; ++n) { 2616 _red_node_index.insert(std::make_pair(converter(map[n]), n)); 2617 } 2618 for (BlueNodeIt n(_graph); n != INVALID; ++n) { 2619 _blue_node_index.insert(std::make_pair(converter(map[n]), n)); 2620 } 2621 return *this; 2622 } 2623 2624 /// \brief Use previously constructed node set 2625 /// 2626 /// Use previously constructed node set, and specify the node 2627 /// label map and a functor which converts the label map values to 2628 /// \c std::string. 2629 template <typename Map, typename Converter> 2630 BpGraphReader& useNodes(const Map& map, 2631 const Converter& converter = Converter()) { 2632 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 2633 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 2634 _use_nodes = true; 2635 for (RedNodeIt n(_graph); n != INVALID; ++n) { 2636 _red_node_index.insert(std::make_pair(converter(map[n]), n)); 2637 } 2638 for (BlueNodeIt n(_graph); n != INVALID; ++n) { 2639 _blue_node_index.insert(std::make_pair(converter(map[n]), n)); 2640 } 2641 return *this; 2642 } 2643 2644 /// \brief Use previously constructed edge set 2645 /// 2646 /// Use previously constructed edge set, and specify the edge 2647 /// label map. 2648 template <typename Map> 2649 BpGraphReader& useEdges(const Map& map) { 2650 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 2651 LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 2652 _use_edges = true; 2653 _writer_bits::DefaultConverter<typename Map::Value> converter; 2654 for (EdgeIt a(_graph); a != INVALID; ++a) { 2655 _edge_index.insert(std::make_pair(converter(map[a]), a)); 2656 } 2657 return *this; 2658 } 2659 2660 /// \brief Use previously constructed edge set 2661 /// 2662 /// Use previously constructed edge set, and specify the edge 2663 /// label map and a functor which converts the label map values to 2664 /// \c std::string. 2665 template <typename Map, typename Converter> 2666 BpGraphReader& useEdges(const Map& map, 2667 const Converter& converter = Converter()) { 2668 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 2669 LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 2670 _use_edges = true; 2671 for (EdgeIt a(_graph); a != INVALID; ++a) { 2672 _edge_index.insert(std::make_pair(converter(map[a]), a)); 2673 } 2674 return *this; 2675 } 2676 2677 /// \brief Skip the reading of node section 2678 /// 2679 /// Omit the reading of the node section. This implies that each node 2680 /// map reading rule will be abandoned, and the nodes of the graph 2681 /// will not be constructed, which usually cause that the edge set 2682 /// could not be read due to lack of node name 2683 /// could not be read due to lack of node name resolving. 2684 /// Therefore \c skipEdges() function should also be used, or 2685 /// \c useNodes() should be used to specify the label of the nodes. 2686 BpGraphReader& skipNodes() { 2687 LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 2688 _skip_nodes = true; 2689 return *this; 2690 } 2691 2692 /// \brief Skip the reading of edge section 2693 /// 2694 /// Omit the reading of the edge section. This implies that each edge 2695 /// map reading rule will be abandoned, and the edges of the graph 2696 /// will not be constructed. 2697 BpGraphReader& skipEdges() { 2698 LEMON_ASSERT(!_skip_edges, "Skip edges already set"); 2699 _skip_edges = true; 2700 return *this; 2701 } 2702 2703 /// @} 2704 2705 private: 2706 2707 bool readLine() { 2708 std::string str; 2709 while(++line_num, std::getline(*_is, str)) { 2710 line.clear(); line.str(str); 2711 char c; 2712 if (line >> std::ws >> c && c != '#') { 2713 line.putback(c); 2714 return true; 2715 } 2716 } 2717 return false; 2718 } 2719 2720 bool readSuccess() { 2721 return static_cast<bool>(*_is); 2722 } 2723 2724 void skipSection() { 2725 char c; 2726 while (readSuccess() && line >> c && c != '@') { 2727 readLine(); 2728 } 2729 if (readSuccess()) { 2730 line.putback(c); 2731 } 2732 } 2733 2734 void readRedNodes() { 2735 2736 std::vector<int> map_index(_red_node_maps.size()); 2737 int map_num, label_index; 2738 2739 char c; 2740 if (!readLine() || !(line >> c) || c == '@') { 2741 if (readSuccess() && line) line.putback(c); 2742 if (!_red_node_maps.empty()) 2743 throw FormatError("Cannot find map names"); 2744 return; 2745 } 2746 line.putback(c); 2747 2748 { 2749 std::map<std::string, int> maps; 2750 2751 std::string map; 2752 int index = 0; 2753 while (_reader_bits::readToken(line, map)) { 2754 if (maps.find(map) != maps.end()) { 2755 std::ostringstream msg; 2756 msg << "Multiple occurence of red node map: " << map; 2757 throw FormatError(msg.str()); 2758 } 2759 maps.insert(std::make_pair(map, index)); 2760 ++index; 2761 } 2762 2763 for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) { 2764 std::map<std::string, int>::iterator jt = 2765 maps.find(_red_node_maps[i].first); 2766 if (jt == maps.end()) { 2767 std::ostringstream msg; 2768 msg << "Map not found: " << _red_node_maps[i].first; 2769 throw FormatError(msg.str()); 2770 } 2771 map_index[i] = jt->second; 2772 } 2773 2774 { 2775 std::map<std::string, int>::iterator jt = maps.find("label"); 2776 if (jt != maps.end()) { 2777 label_index = jt->second; 2778 } else { 2779 label_index = -1; 2780 } 2781 } 2782 map_num = maps.size(); 2783 } 2784 2785 while (readLine() && line >> c && c != '@') { 2786 line.putback(c); 2787 2788 std::vector<std::string> tokens(map_num); 2789 for (int i = 0; i < map_num; ++i) { 2790 if (!_reader_bits::readToken(line, tokens[i])) { 2791 std::ostringstream msg; 2792 msg << "Column not found (" << i + 1 << ")"; 2793 throw FormatError(msg.str()); 2794 } 2795 } 2796 if (line >> std::ws >> c) 2797 throw FormatError("Extra character at the end of line"); 2798 2799 RedNode n; 2800 if (!_use_nodes) { 2801 n = _graph.addRedNode(); 2802 if (label_index != -1) 2803 _red_node_index.insert(std::make_pair(tokens[label_index], n)); 2804 } else { 2805 if (label_index == -1) 2806 throw FormatError("Label map not found"); 2807 typename std::map<std::string, RedNode>::iterator it = 2808 _red_node_index.find(tokens[label_index]); 2809 if (it == _red_node_index.end()) { 2810 std::ostringstream msg; 2811 msg << "Node with label not found: " << tokens[label_index]; 2812 throw FormatError(msg.str()); 2813 } 2814 n = it->second; 2815 } 2816 2817 for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) { 2818 _red_node_maps[i].second->set(n, tokens[map_index[i]]); 2819 } 2820 2821 } 2822 if (readSuccess()) { 2823 line.putback(c); 2824 } 2825 } 2826 2827 void readBlueNodes() { 2828 2829 std::vector<int> map_index(_blue_node_maps.size()); 2830 int map_num, label_index; 2831 2832 char c; 2833 if (!readLine() || !(line >> c) || c == '@') { 2834 if (readSuccess() && line) line.putback(c); 2835 if (!_blue_node_maps.empty()) 2836 throw FormatError("Cannot find map names"); 2837 return; 2838 } 2839 line.putback(c); 2840 2841 { 2842 std::map<std::string, int> maps; 2843 2844 std::string map; 2845 int index = 0; 2846 while (_reader_bits::readToken(line, map)) { 2847 if (maps.find(map) != maps.end()) { 2848 std::ostringstream msg; 2849 msg << "Multiple occurence of blue node map: " << map; 2850 throw FormatError(msg.str()); 2851 } 2852 maps.insert(std::make_pair(map, index)); 2853 ++index; 2854 } 2855 2856 for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) { 2857 std::map<std::string, int>::iterator jt = 2858 maps.find(_blue_node_maps[i].first); 2859 if (jt == maps.end()) { 2860 std::ostringstream msg; 2861 msg << "Map not found: " << _blue_node_maps[i].first; 2862 throw FormatError(msg.str()); 2863 } 2864 map_index[i] = jt->second; 2865 } 2866 2867 { 2868 std::map<std::string, int>::iterator jt = maps.find("label"); 2869 if (jt != maps.end()) { 2870 label_index = jt->second; 2871 } else { 2872 label_index = -1; 2873 } 2874 } 2875 map_num = maps.size(); 2876 } 2877 2878 while (readLine() && line >> c && c != '@') { 2879 line.putback(c); 2880 2881 std::vector<std::string> tokens(map_num); 2882 for (int i = 0; i < map_num; ++i) { 2883 if (!_reader_bits::readToken(line, tokens[i])) { 2884 std::ostringstream msg; 2885 msg << "Column not found (" << i + 1 << ")"; 2886 throw FormatError(msg.str()); 2887 } 2888 } 2889 if (line >> std::ws >> c) 2890 throw FormatError("Extra character at the end of line"); 2891 2892 BlueNode n; 2893 if (!_use_nodes) { 2894 n = _graph.addBlueNode(); 2895 if (label_index != -1) 2896 _blue_node_index.insert(std::make_pair(tokens[label_index], n)); 2897 } else { 2898 if (label_index == -1) 2899 throw FormatError("Label map not found"); 2900 typename std::map<std::string, BlueNode>::iterator it = 2901 _blue_node_index.find(tokens[label_index]); 2902 if (it == _blue_node_index.end()) { 2903 std::ostringstream msg; 2904 msg << "Node with label not found: " << tokens[label_index]; 2905 throw FormatError(msg.str()); 2906 } 2907 n = it->second; 2908 } 2909 2910 for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) { 2911 _blue_node_maps[i].second->set(n, tokens[map_index[i]]); 2912 } 2913 2914 } 2915 if (readSuccess()) { 2916 line.putback(c); 2917 } 2918 } 2919 2920 void readEdges() { 2921 2922 std::vector<int> map_index(_edge_maps.size()); 2923 int map_num, label_index; 2924 2925 char c; 2926 if (!readLine() || !(line >> c) || c == '@') { 2927 if (readSuccess() && line) line.putback(c); 2928 if (!_edge_maps.empty()) 2929 throw FormatError("Cannot find map names"); 2930 return; 2931 } 2932 line.putback(c); 2933 2934 { 2935 std::map<std::string, int> maps; 2936 2937 std::string map; 2938 int index = 0; 2939 while (_reader_bits::readToken(line, map)) { 2940 if (maps.find(map) != maps.end()) { 2941 std::ostringstream msg; 2942 msg << "Multiple occurence of edge map: " << map; 2943 throw FormatError(msg.str()); 2944 } 2945 maps.insert(std::make_pair(map, index)); 2946 ++index; 2947 } 2948 2949 for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) { 2950 std::map<std::string, int>::iterator jt = 2951 maps.find(_edge_maps[i].first); 2952 if (jt == maps.end()) { 2953 std::ostringstream msg; 2954 msg << "Map not found: " << _edge_maps[i].first; 2955 throw FormatError(msg.str()); 2956 } 2957 map_index[i] = jt->second; 2958 } 2959 2960 { 2961 std::map<std::string, int>::iterator jt = maps.find("label"); 2962 if (jt != maps.end()) { 2963 label_index = jt->second; 2964 } else { 2965 label_index = -1; 2966 } 2967 } 2968 map_num = maps.size(); 2969 } 2970 2971 while (readLine() && line >> c && c != '@') { 2972 line.putback(c); 2973 2974 std::string source_token; 2975 std::string target_token; 2976 2977 if (!_reader_bits::readToken(line, source_token)) 2978 throw FormatError("Red node not found"); 2979 2980 if (!_reader_bits::readToken(line, target_token)) 2981 throw FormatError("Blue node not found"); 2982 2983 std::vector<std::string> tokens(map_num); 2984 for (int i = 0; i < map_num; ++i) { 2985 if (!_reader_bits::readToken(line, tokens[i])) { 2986 std::ostringstream msg; 2987 msg << "Column not found (" << i + 1 << ")"; 2988 throw FormatError(msg.str()); 2989 } 2990 } 2991 if (line >> std::ws >> c) 2992 throw FormatError("Extra character at the end of line"); 2993 2994 Edge e; 2995 if (!_use_edges) { 2996 typename RedNodeIndex::iterator rit = 2997 _red_node_index.find(source_token); 2998 if (rit == _red_node_index.end()) { 2999 std::ostringstream msg; 3000 msg << "Item not found: " << source_token; 3001 throw FormatError(msg.str()); 3002 } 3003 RedNode source = rit->second; 3004 typename BlueNodeIndex::iterator it = 3005 _blue_node_index.find(target_token); 3006 if (it == _blue_node_index.end()) { 3007 std::ostringstream msg; 3008 msg << "Item not found: " << target_token; 3009 throw FormatError(msg.str()); 3010 } 3011 BlueNode target = it->second; 3012 3013 // It is checked that source is red and 3014 // target is blue, so this should be safe: 3015 e = _graph.addEdge(source, target); 3016 if (label_index != -1) 3017 _edge_index.insert(std::make_pair(tokens[label_index], e)); 3018 } else { 3019 if (label_index == -1) 3020 throw FormatError("Label map not found"); 3021 typename std::map<std::string, Edge>::iterator it = 3022 _edge_index.find(tokens[label_index]); 3023 if (it == _edge_index.end()) { 3024 std::ostringstream msg; 3025 msg << "Edge with label not found: " << tokens[label_index]; 3026 throw FormatError(msg.str()); 3027 } 3028 e = it->second; 3029 } 3030 3031 for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) { 3032 _edge_maps[i].second->set(e, tokens[map_index[i]]); 3033 } 3034 3035 } 3036 if (readSuccess()) { 3037 line.putback(c); 3038 } 3039 } 3040 3041 void readAttributes() { 3042 3043 std::set<std::string> read_attr; 3044 3045 char c; 3046 while (readLine() && line >> c && c != '@') { 3047 line.putback(c); 3048 3049 std::string attr, token; 3050 if (!_reader_bits::readToken(line, attr)) 3051 throw FormatError("Attribute name not found"); 3052 if (!_reader_bits::readToken(line, token)) 3053 throw FormatError("Attribute value not found"); 3054 if (line >> c) 3055 throw FormatError("Extra character at the end of line"); 3056 3057 { 3058 std::set<std::string>::iterator it = read_attr.find(attr); 3059 if (it != read_attr.end()) { 3060 std::ostringstream msg; 3061 msg << "Multiple occurence of attribute: " << attr; 3062 throw FormatError(msg.str()); 3063 } 3064 read_attr.insert(attr); 3065 } 3066 3067 { 3068 typename Attributes::iterator it = _attributes.lower_bound(attr); 3069 while (it != _attributes.end() && it->first == attr) { 3070 it->second->set(token); 3071 ++it; 3072 } 3073 } 3074 3075 } 3076 if (readSuccess()) { 3077 line.putback(c); 3078 } 3079 for (typename Attributes::iterator it = _attributes.begin(); 3080 it != _attributes.end(); ++it) { 3081 if (read_attr.find(it->first) == read_attr.end()) { 3082 std::ostringstream msg; 3083 msg << "Attribute not found: " << it->first; 3084 throw FormatError(msg.str()); 3085 } 3086 } 3087 } 3088 3089 public: 3090 3091 /// \name Execution of the Reader 3092 /// @{ 3093 3094 /// \brief Start the batch processing 3095 /// 3096 /// This function starts the batch processing 3097 void run() { 3098 3099 LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); 3100 3101 bool red_nodes_done = _skip_nodes; 3102 bool blue_nodes_done = _skip_nodes; 3103 bool edges_done = _skip_edges; 3104 bool attributes_done = false; 3105 3106 line_num = 0; 3107 readLine(); 3108 skipSection(); 3109 3110 while (readSuccess()) { 3111 try { 3112 char c; 3113 std::string section, caption; 3114 line >> c; 3115 _reader_bits::readToken(line, section); 3116 _reader_bits::readToken(line, caption); 3117 3118 if (line >> c) 3119 throw FormatError("Extra character at the end of line"); 3120 3121 if (section == "red_nodes" && !red_nodes_done) { 3122 if (_nodes_caption.empty() || _nodes_caption == caption) { 3123 readRedNodes(); 3124 red_nodes_done = true; 3125 } 3126 } else if (section == "blue_nodes" && !blue_nodes_done) { 3127 if (_nodes_caption.empty() || _nodes_caption == caption) { 3128 readBlueNodes(); 3129 blue_nodes_done = true; 3130 } 3131 } else if ((section == "edges" || section == "arcs") && 3132 !edges_done) { 3133 if (_edges_caption.empty() || _edges_caption == caption) { 3134 readEdges(); 3135 edges_done = true; 3136 } 3137 } else if (section == "attributes" && !attributes_done) { 3138 if (_attributes_caption.empty() || _attributes_caption == caption) { 3139 readAttributes(); 3140 attributes_done = true; 3141 } 3142 } else { 3143 readLine(); 3144 skipSection(); 3145 } 3146 } catch (FormatError& error) { 3147 error.line(line_num); 3148 error.file(_filename); 3149 throw; 3150 } 3151 } 3152 3153 if (!red_nodes_done) { 3154 throw FormatError("Section @red_nodes not found"); 3155 } 3156 3157 if (!blue_nodes_done) { 3158 throw FormatError("Section @blue_nodes not found"); 3159 } 3160 3161 if (!edges_done) { 3162 throw FormatError("Section @edges not found"); 3163 } 3164 3165 if (!attributes_done && !_attributes.empty()) { 3166 throw FormatError("Section @attributes not found"); 3167 } 3168 3169 } 3170 3171 /// @} 3172 3173 }; 3174 3175 /// \ingroup lemon_io 3176 /// 3177 /// \brief Return a \ref BpGraphReader class 3178 /// 3179 /// This function just returns a \ref BpGraphReader class. 3180 /// 3181 /// With this function a graph can be read from an 3182 /// \ref lgf-format "LGF" file or input stream with several maps and 3183 /// attributes. For example, there is bipartite weighted matching problem 3184 /// on a graph, i.e. a graph with a \e weight map on the edges. This 3185 /// graph can be read with the following code: 3186 /// 3187 ///\code 3188 ///ListBpGraph graph; 3189 ///ListBpGraph::EdgeMap<int> weight(graph); 3190 ///bpGraphReader(graph, std::cin). 3191 /// edgeMap("weight", weight). 3192 /// run(); 3193 ///\endcode 3194 /// 3195 /// For a complete documentation, please see the \ref BpGraphReader 3196 /// class documentation. 3197 /// \warning Don't forget to put the \ref BpGraphReader::run() "run()" 3198 /// to the end of the parameter list. 3199 /// \relates BpGraphReader 3200 /// \sa bpGraphReader(TBGR& graph, const std::string& fn) 3201 /// \sa bpGraphReader(TBGR& graph, const char* fn) 3202 template <typename TBGR> 3203 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is) { 3204 BpGraphReader<TBGR> tmp(graph, is); 3205 return tmp; 3206 } 3207 3208 /// \brief Return a \ref BpGraphReader class 3209 /// 3210 /// This function just returns a \ref BpGraphReader class. 3211 /// \relates BpGraphReader 3212 /// \sa bpGraphReader(TBGR& graph, std::istream& is) 3213 template <typename TBGR> 3214 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn) { 3215 BpGraphReader<TBGR> tmp(graph, fn); 3216 return tmp; 3217 } 3218 3219 /// \brief Return a \ref BpGraphReader class 3220 /// 3221 /// This function just returns a \ref BpGraphReader class. 3222 /// \relates BpGraphReader 3223 /// \sa bpGraphReader(TBGR& graph, std::istream& is) 3224 template <typename TBGR> 3225 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char* fn) { 3226 BpGraphReader<TBGR> tmp(graph, fn); 3227 return tmp; 3228 } 3229 2131 3230 class SectionReader; 2132 3231
Note: See TracChangeset
for help on using the changeset viewer.