152 virtual void set(const std::string& value) { |
152 virtual void set(const std::string& value) { |
153 _value = _converter(value); |
153 _value = _converter(value); |
154 } |
154 } |
155 }; |
155 }; |
156 |
156 |
157 template <typename Value> |
157 template <typename Value, |
|
158 typename Map = std::map<std::string, Value> > |
158 struct MapLookUpConverter { |
159 struct MapLookUpConverter { |
159 const std::map<std::string, Value>& _map; |
160 const Map& _map; |
160 |
161 |
161 MapLookUpConverter(const std::map<std::string, Value>& map) |
162 MapLookUpConverter(const Map& map) |
162 : _map(map) {} |
163 : _map(map) {} |
163 |
164 |
164 Value operator()(const std::string& str) { |
165 Value operator()(const std::string& str) { |
165 typename std::map<std::string, Value>::const_iterator it = |
166 typename Map::const_iterator it = _map.find(str); |
166 _map.find(str); |
|
167 if (it == _map.end()) { |
167 if (it == _map.end()) { |
168 std::ostringstream msg; |
168 std::ostringstream msg; |
169 msg << "Item not found: " << str; |
169 msg << "Item not found: " << str; |
170 throw FormatError(msg.str()); |
170 throw FormatError(msg.str()); |
171 } |
171 } |
172 return it->second; |
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 }; |
175 |
208 |
176 template <typename GR> |
209 template <typename GR> |
177 struct GraphArcLookUpConverter { |
210 struct GraphArcLookUpConverter { |
2169 |
2202 |
2170 std::string _nodes_caption; |
2203 std::string _nodes_caption; |
2171 std::string _edges_caption; |
2204 std::string _edges_caption; |
2172 std::string _attributes_caption; |
2205 std::string _attributes_caption; |
2173 |
2206 |
2174 typedef std::map<std::string, Node> NodeIndex; |
2207 typedef std::map<std::string, RedNode> RedNodeIndex; |
2175 NodeIndex _node_index; |
2208 RedNodeIndex _red_node_index; |
|
2209 typedef std::map<std::string, BlueNode> BlueNodeIndex; |
|
2210 BlueNodeIndex _blue_node_index; |
2176 typedef std::map<std::string, Edge> EdgeIndex; |
2211 typedef std::map<std::string, Edge> EdgeIndex; |
2177 EdgeIndex _edge_index; |
2212 EdgeIndex _edge_index; |
2178 |
2213 |
2179 typedef std::vector<std::pair<std::string, |
2214 typedef std::vector<std::pair<std::string, |
2180 _reader_bits::MapStorageBase<Node>*> > NodeMaps; |
2215 _reader_bits::MapStorageBase<RedNode>*> > RedNodeMaps; |
2181 NodeMaps _red_maps; |
2216 RedNodeMaps _red_node_maps; |
2182 NodeMaps _blue_maps; |
2217 typedef std::vector<std::pair<std::string, |
|
2218 _reader_bits::MapStorageBase<BlueNode>*> > BlueNodeMaps; |
|
2219 BlueNodeMaps _blue_node_maps; |
2183 |
2220 |
2184 typedef std::vector<std::pair<std::string, |
2221 typedef std::vector<std::pair<std::string, |
2185 _reader_bits::MapStorageBase<Edge>*> > EdgeMaps; |
2222 _reader_bits::MapStorageBase<Edge>*> > EdgeMaps; |
2186 EdgeMaps _edge_maps; |
2223 EdgeMaps _edge_maps; |
2187 |
2224 |
2309 /// |
2347 /// |
2310 /// Add a node map reading rule to the reader. |
2348 /// Add a node map reading rule to the reader. |
2311 template <typename Map> |
2349 template <typename Map> |
2312 BpGraphReader& nodeMap(const std::string& caption, Map& map) { |
2350 BpGraphReader& nodeMap(const std::string& caption, Map& map) { |
2313 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
2351 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
2314 _reader_bits::MapStorageBase<Node>* red_storage = |
2352 _reader_bits::MapStorageBase<RedNode>* red_storage = |
2315 new _reader_bits::MapStorage<Node, Map>(map); |
2353 new _reader_bits::MapStorage<RedNode, Map>(map); |
2316 _red_maps.push_back(std::make_pair(caption, red_storage)); |
2354 _red_node_maps.push_back(std::make_pair(caption, red_storage)); |
2317 _reader_bits::MapStorageBase<Node>* blue_storage = |
2355 _reader_bits::MapStorageBase<BlueNode>* blue_storage = |
2318 new _reader_bits::MapStorage<Node, Map>(map); |
2356 new _reader_bits::MapStorage<BlueNode, Map>(map); |
2319 _blue_maps.push_back(std::make_pair(caption, blue_storage)); |
2357 _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); |
2320 return *this; |
2358 return *this; |
2321 } |
2359 } |
2322 |
2360 |
2323 /// \brief Node map reading rule |
2361 /// \brief Node map reading rule |
2324 /// |
2362 /// |
2326 /// reader. |
2364 /// reader. |
2327 template <typename Map, typename Converter> |
2365 template <typename Map, typename Converter> |
2328 BpGraphReader& nodeMap(const std::string& caption, Map& map, |
2366 BpGraphReader& nodeMap(const std::string& caption, Map& map, |
2329 const Converter& converter = Converter()) { |
2367 const Converter& converter = Converter()) { |
2330 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
2368 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
2331 _reader_bits::MapStorageBase<Node>* red_storage = |
2369 _reader_bits::MapStorageBase<RedNode>* red_storage = |
2332 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
2370 new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter); |
2333 _red_maps.push_back(std::make_pair(caption, red_storage)); |
2371 _red_node_maps.push_back(std::make_pair(caption, red_storage)); |
2334 _reader_bits::MapStorageBase<Node>* blue_storage = |
2372 _reader_bits::MapStorageBase<BlueNode>* blue_storage = |
2335 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
2373 new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter); |
2336 _blue_maps.push_back(std::make_pair(caption, blue_storage)); |
2374 _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); |
2337 return *this; |
2375 return *this; |
2338 } |
2376 } |
2339 |
2377 |
2340 /// Add a red node map reading rule to the reader. |
2378 /// Add a red node map reading rule to the reader. |
2341 template <typename Map> |
2379 template <typename Map> |
2342 BpGraphReader& redNodeMap(const std::string& caption, Map& map) { |
2380 BpGraphReader& redNodeMap(const std::string& caption, Map& map) { |
2343 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
2381 checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>(); |
2344 _reader_bits::MapStorageBase<Node>* storage = |
2382 _reader_bits::MapStorageBase<RedNode>* storage = |
2345 new _reader_bits::MapStorage<Node, Map>(map); |
2383 new _reader_bits::MapStorage<RedNode, Map>(map); |
2346 _red_maps.push_back(std::make_pair(caption, storage)); |
2384 _red_node_maps.push_back(std::make_pair(caption, storage)); |
2347 return *this; |
2385 return *this; |
2348 } |
2386 } |
2349 |
2387 |
2350 /// \brief Red node map reading rule |
2388 /// \brief Red node map reading rule |
2351 /// |
2389 /// |
2352 /// Add a red node map node reading rule with specialized converter to |
2390 /// Add a red node map node reading rule with specialized converter to |
2353 /// the reader. |
2391 /// the reader. |
2354 template <typename Map, typename Converter> |
2392 template <typename Map, typename Converter> |
2355 BpGraphReader& redNodeMap(const std::string& caption, Map& map, |
2393 BpGraphReader& redNodeMap(const std::string& caption, Map& map, |
2356 const Converter& converter = Converter()) { |
2394 const Converter& converter = Converter()) { |
2357 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
2395 checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>(); |
2358 _reader_bits::MapStorageBase<Node>* storage = |
2396 _reader_bits::MapStorageBase<RedNode>* storage = |
2359 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
2397 new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter); |
2360 _red_maps.push_back(std::make_pair(caption, storage)); |
2398 _red_node_maps.push_back(std::make_pair(caption, storage)); |
2361 return *this; |
2399 return *this; |
2362 } |
2400 } |
2363 |
2401 |
2364 /// Add a blue node map reading rule to the reader. |
2402 /// Add a blue node map reading rule to the reader. |
2365 template <typename Map> |
2403 template <typename Map> |
2366 BpGraphReader& blueNodeMap(const std::string& caption, Map& map) { |
2404 BpGraphReader& blueNodeMap(const std::string& caption, Map& map) { |
2367 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
2405 checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>(); |
2368 _reader_bits::MapStorageBase<Node>* storage = |
2406 _reader_bits::MapStorageBase<BlueNode>* storage = |
2369 new _reader_bits::MapStorage<Node, Map>(map); |
2407 new _reader_bits::MapStorage<BlueNode, Map>(map); |
2370 _blue_maps.push_back(std::make_pair(caption, storage)); |
2408 _blue_node_maps.push_back(std::make_pair(caption, storage)); |
2371 return *this; |
2409 return *this; |
2372 } |
2410 } |
2373 |
2411 |
2374 /// \brief Blue node map reading rule |
2412 /// \brief Blue node map reading rule |
2375 /// |
2413 /// |
2376 /// Add a blue node map reading rule with specialized converter to |
2414 /// Add a blue node map reading rule with specialized converter to |
2377 /// the reader. |
2415 /// the reader. |
2378 template <typename Map, typename Converter> |
2416 template <typename Map, typename Converter> |
2379 BpGraphReader& blueNodeMap(const std::string& caption, Map& map, |
2417 BpGraphReader& blueNodeMap(const std::string& caption, Map& map, |
2380 const Converter& converter = Converter()) { |
2418 const Converter& converter = Converter()) { |
2381 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
2419 checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>(); |
2382 _reader_bits::MapStorageBase<Node>* storage = |
2420 _reader_bits::MapStorageBase<BlueNode>* storage = |
2383 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
2421 new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter); |
2384 _blue_maps.push_back(std::make_pair(caption, storage)); |
2422 _blue_node_maps.push_back(std::make_pair(caption, storage)); |
2385 return *this; |
2423 return *this; |
2386 } |
2424 } |
2387 |
2425 |
2388 /// \brief Edge map reading rule |
2426 /// \brief Edge map reading rule |
2389 /// |
2427 /// |
2471 |
2509 |
2472 /// \brief Node reading rule |
2510 /// \brief Node reading rule |
2473 /// |
2511 /// |
2474 /// Add a node reading rule to reader. |
2512 /// Add a node reading rule to reader. |
2475 BpGraphReader& node(const std::string& caption, Node& node) { |
2513 BpGraphReader& node(const std::string& caption, Node& node) { |
2476 typedef _reader_bits::MapLookUpConverter<Node> Converter; |
2514 typedef _reader_bits::DoubleMapLookUpConverter< |
2477 Converter converter(_node_index); |
2515 Node, RedNodeIndex, BlueNodeIndex> Converter; |
|
2516 Converter converter(_red_node_index, _blue_node_index); |
2478 _reader_bits::ValueStorageBase* storage = |
2517 _reader_bits::ValueStorageBase* storage = |
2479 new _reader_bits::ValueStorage<Node, Converter>(node, converter); |
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); |
2480 _attributes.insert(std::make_pair(caption, storage)); |
2543 _attributes.insert(std::make_pair(caption, storage)); |
2481 return *this; |
2544 return *this; |
2482 } |
2545 } |
2483 |
2546 |
2484 /// \brief Edge reading rule |
2547 /// \brief Edge reading rule |
2725 } |
2794 } |
2726 } |
2795 } |
2727 if (line >> std::ws >> c) |
2796 if (line >> std::ws >> c) |
2728 throw FormatError("Extra character at the end of line"); |
2797 throw FormatError("Extra character at the end of line"); |
2729 |
2798 |
2730 Node n; |
2799 RedNode n; |
2731 if (!_use_nodes) { |
2800 if (!_use_nodes) { |
2732 n = _graph.addRedNode(); |
2801 n = _graph.addRedNode(); |
2733 if (label_index != -1) |
2802 if (label_index != -1) |
2734 _node_index.insert(std::make_pair(tokens[label_index], n)); |
2803 _red_node_index.insert(std::make_pair(tokens[label_index], n)); |
2735 } else { |
2804 } else { |
2736 if (label_index == -1) |
2805 if (label_index == -1) |
2737 throw FormatError("Label map not found"); |
2806 throw FormatError("Label map not found"); |
2738 typename std::map<std::string, Node>::iterator it = |
2807 typename std::map<std::string, RedNode>::iterator it = |
2739 _node_index.find(tokens[label_index]); |
2808 _red_node_index.find(tokens[label_index]); |
2740 if (it == _node_index.end()) { |
2809 if (it == _red_node_index.end()) { |
2741 std::ostringstream msg; |
2810 std::ostringstream msg; |
2742 msg << "Node with label not found: " << tokens[label_index]; |
2811 msg << "Node with label not found: " << tokens[label_index]; |
2743 throw FormatError(msg.str()); |
2812 throw FormatError(msg.str()); |
2744 } |
2813 } |
2745 n = it->second; |
2814 n = it->second; |
2746 } |
2815 } |
2747 |
2816 |
2748 for (int i = 0; i < static_cast<int>(_red_maps.size()); ++i) { |
2817 for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) { |
2749 _red_maps[i].second->set(n, tokens[map_index[i]]); |
2818 _red_node_maps[i].second->set(n, tokens[map_index[i]]); |
2750 } |
2819 } |
2751 |
2820 |
2752 } |
2821 } |
2753 if (readSuccess()) { |
2822 if (readSuccess()) { |
2754 line.putback(c); |
2823 line.putback(c); |
2755 } |
2824 } |
2756 } |
2825 } |
2757 |
2826 |
2758 void readBlueNodes() { |
2827 void readBlueNodes() { |
2759 |
2828 |
2760 std::vector<int> map_index(_blue_maps.size()); |
2829 std::vector<int> map_index(_blue_node_maps.size()); |
2761 int map_num, label_index; |
2830 int map_num, label_index; |
2762 |
2831 |
2763 char c; |
2832 char c; |
2764 if (!readLine() || !(line >> c) || c == '@') { |
2833 if (!readLine() || !(line >> c) || c == '@') { |
2765 if (readSuccess() && line) line.putback(c); |
2834 if (readSuccess() && line) line.putback(c); |
2766 if (!_blue_maps.empty()) |
2835 if (!_blue_node_maps.empty()) |
2767 throw FormatError("Cannot find map names"); |
2836 throw FormatError("Cannot find map names"); |
2768 return; |
2837 return; |
2769 } |
2838 } |
2770 line.putback(c); |
2839 line.putback(c); |
2771 |
2840 |
2818 } |
2887 } |
2819 } |
2888 } |
2820 if (line >> std::ws >> c) |
2889 if (line >> std::ws >> c) |
2821 throw FormatError("Extra character at the end of line"); |
2890 throw FormatError("Extra character at the end of line"); |
2822 |
2891 |
2823 Node n; |
2892 BlueNode n; |
2824 if (!_use_nodes) { |
2893 if (!_use_nodes) { |
2825 n = _graph.addBlueNode(); |
2894 n = _graph.addBlueNode(); |
2826 if (label_index != -1) |
2895 if (label_index != -1) |
2827 _node_index.insert(std::make_pair(tokens[label_index], n)); |
2896 _blue_node_index.insert(std::make_pair(tokens[label_index], n)); |
2828 } else { |
2897 } else { |
2829 if (label_index == -1) |
2898 if (label_index == -1) |
2830 throw FormatError("Label map not found"); |
2899 throw FormatError("Label map not found"); |
2831 typename std::map<std::string, Node>::iterator it = |
2900 typename std::map<std::string, BlueNode>::iterator it = |
2832 _node_index.find(tokens[label_index]); |
2901 _blue_node_index.find(tokens[label_index]); |
2833 if (it == _node_index.end()) { |
2902 if (it == _blue_node_index.end()) { |
2834 std::ostringstream msg; |
2903 std::ostringstream msg; |
2835 msg << "Node with label not found: " << tokens[label_index]; |
2904 msg << "Node with label not found: " << tokens[label_index]; |
2836 throw FormatError(msg.str()); |
2905 throw FormatError(msg.str()); |
2837 } |
2906 } |
2838 n = it->second; |
2907 n = it->second; |
2839 } |
2908 } |
2840 |
2909 |
2841 for (int i = 0; i < static_cast<int>(_blue_maps.size()); ++i) { |
2910 for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) { |
2842 _blue_maps[i].second->set(n, tokens[map_index[i]]); |
2911 _blue_node_maps[i].second->set(n, tokens[map_index[i]]); |
2843 } |
2912 } |
2844 |
2913 |
2845 } |
2914 } |
2846 if (readSuccess()) { |
2915 if (readSuccess()) { |
2847 line.putback(c); |
2916 line.putback(c); |
2922 if (line >> std::ws >> c) |
2991 if (line >> std::ws >> c) |
2923 throw FormatError("Extra character at the end of line"); |
2992 throw FormatError("Extra character at the end of line"); |
2924 |
2993 |
2925 Edge e; |
2994 Edge e; |
2926 if (!_use_edges) { |
2995 if (!_use_edges) { |
2927 |
2996 typename RedNodeIndex::iterator rit = |
2928 typename NodeIndex::iterator it; |
2997 _red_node_index.find(source_token); |
2929 |
2998 if (rit == _red_node_index.end()) { |
2930 it = _node_index.find(source_token); |
|
2931 if (it == _node_index.end()) { |
|
2932 std::ostringstream msg; |
2999 std::ostringstream msg; |
2933 msg << "Item not found: " << source_token; |
3000 msg << "Item not found: " << source_token; |
2934 throw FormatError(msg.str()); |
3001 throw FormatError(msg.str()); |
2935 } |
3002 } |
2936 Node source = it->second; |
3003 RedNode source = rit->second; |
2937 if (!_graph.red(source)) { |
3004 typename BlueNodeIndex::iterator it = |
2938 std::ostringstream msg; |
3005 _blue_node_index.find(target_token); |
2939 msg << "Item is not red node: " << source_token; |
3006 if (it == _blue_node_index.end()) { |
2940 throw FormatError(msg.str()); |
|
2941 } |
|
2942 |
|
2943 it = _node_index.find(target_token); |
|
2944 if (it == _node_index.end()) { |
|
2945 std::ostringstream msg; |
3007 std::ostringstream msg; |
2946 msg << "Item not found: " << target_token; |
3008 msg << "Item not found: " << target_token; |
2947 throw FormatError(msg.str()); |
3009 throw FormatError(msg.str()); |
2948 } |
3010 } |
2949 Node target = it->second; |
3011 BlueNode target = it->second; |
2950 if (!_graph.blue(target)) { |
|
2951 std::ostringstream msg; |
|
2952 msg << "Item is not red node: " << source_token; |
|
2953 throw FormatError(msg.str()); |
|
2954 } |
|
2955 |
3012 |
2956 // It is checked that source is red and |
3013 // It is checked that source is red and |
2957 // target is blue, so this should be safe: |
3014 // target is blue, so this should be safe: |
2958 e = _graph.addEdge(_graph.asRedNodeUnsafe(source), |
3015 e = _graph.addEdge(source, target); |
2959 _graph.asBlueNodeUnsafe(target)); |
|
2960 if (label_index != -1) |
3016 if (label_index != -1) |
2961 _edge_index.insert(std::make_pair(tokens[label_index], e)); |
3017 _edge_index.insert(std::make_pair(tokens[label_index], e)); |
2962 } else { |
3018 } else { |
2963 if (label_index == -1) |
3019 if (label_index == -1) |
2964 throw FormatError("Label map not found"); |
3020 throw FormatError("Label map not found"); |